【问题标题】:Type of unpacked argument解压参数的类型
【发布时间】:2013-06-15 03:19:54
【问题描述】:

我有以下代码:

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";
}

它使用 Lambda 解包并将每个参数推送到向量中(我使用 lambda 来避免递归的空模板函数;我更喜欢嵌套的 lambda)。但是,它需要使用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)...};
    };

测试它是否是字面的,但它是不正确的。如何修复它并测试每个参数是否是文字?

【问题讨论】:

  • 为什么需要特别检测文字?您想要的是检测是否可以在to_string() 的输入中给出类型
  • 好吧,我想通过检测它是否是文字,我可以选择不将它传递给 to_string()。那不是一样的吗?两种方式我都卡住了。

标签: c++ c++11 lambda variadic-templates


【解决方案1】:

您可以定义自己的to_string 版本:

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

然后将您的 lambda 主体更改为:

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

编辑:实际上,在std 中定义to_string 可能更好:

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

【讨论】:

  • 或者干脆using std::to_string
  • @0x499602D2 不,我认为它不会起作用。这可以启用 ADL,但它并没有那么有用,因为这里使用 const char* 操作。实际上,最好将自己的 to_string 添加到 std 命名空间。 @CantChooseUsernames
  • :) 谢谢@catscradle;我将 to_string 添加到命名空间 std 并且效果很好!我将它模板化为使用 is_literal 和类型 T,因此它不仅仅是 const char*,而是所有其他类型的“字符串”:)
猜你喜欢
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多