0

次のコードがあります。

template<typename... Args>
void Print(const char* Text, Args... args)
{
    std::vector<std::string> ArgumentList;
    std::function<void(Args... A)> Unpack = [&] (Args... A)
    {
        auto l = {(ArgumentList.push_back(std::to_string(A)), 0)...};
    };

    Unpack(args...);

    for (auto it = ArgumentList.begin(); it != ArgumentList.end(); ++it)
        std::cout<<*it<<"\n";
}

ラムダを使用して各引数をアンパックし、ベクトルにプッシュします (再帰的な空のテンプレート関数を避けるためにラムダを使用しました。ネストされたラムダを好みます)。std::to_string(..)ただし、ベクターは文字列のみを受け入れるため、使用する必要があります。したがって、私がするとき:

Print("%", "One", "Two", 5);

"One""Two"はすでにリテラルであり、std::to_string整数型のみを受け取るため、コンパイルされません。

どのタイプの「引数」が渡されているかをどのように把握できますか? 私は試した:

template<typename T>
struct is_literal
{
    enum {value = false};
};

template<>
struct is_literal<TCHAR>
{
    enum {value = true};
};

template<>
struct is_literal<TCHAR*>
{
    enum {value = true};
};

template<>
struct is_literal<const TCHAR*>
{
    enum {value = true};
};

template<typename Char, typename Traits, typename Alloc>
struct is_literal<std::basic_string<Char, Traits, Alloc>>
{
    enum
    {
        value = true
    };
};

しかし、これはテンプレート パラメーターではないため、引数で使用できないことに気付きましたか?

私がやりたかった:

std::function<void(Args... A)> Unpack = [&] (Args... A)
    {
        auto l = {(ArgumentList.push_back(is_literal<A>() ? A, std::to_string(A)), 0)...};
    };

それが文字通りかどうかをテストしますが、正しくありません。各引数がリテラルかどうかを修正してテストするにはどうすればよいですか?

4

1 に答える 1

2

to_string独自のバージョンを定義できます。

std::string to_string(const char* s) {
    return s;
}

次に、ラムダ本体を次のように変更します。

using namespace std;
auto l = {(ArgumentList.push_back(to_string(A)), 0)...};

to_string編集:実際には、内部を定義する方がおそらく良いでしょうstd:

namespace std {
    std::string to_string(const char* s) {
        return s;
    }
}
于 2013-06-18T19:14:48.577 に答える