3

正如我知道如何将模板函数作为模板参数传递一样,我现在正努力以类似的方式传递变量模板。

这是我尝试过的最小示例:

#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
                                                    {return name<decltype(args)...>;}

//testing
template <typename T>
bool value = std::is_fundamental<T>::value;

template <typename Hax>
void print_bool(Hax h)
{
    std::cout << h(int{}) << std::endl; // no error, wrong output
    //std::cout << h(int{}, float{}) << std::endl; // error, good
}

int main()
{
    print_bool(PASS_VARIABLE_TEMPLATE(value)); //prints 0 instead of 1
}

演示

如果它编译,那么为什么输出是错误的?

4

2 回答 2

3

您的代码的主要问题是decltype将参数推断为rvalue引用 ( int&&),因为您的 lambda 使用转发引用来接受参数。 std::is_fundamental将适用于类型。

对于您的特定代码段,正确的解决方案是删除参考

#define PASS_VARIABLE_TEMPLATE(name) \
    [dummy=nullptr](auto&&...args){return name<std::remove_reference_t<decltype(args)>...>;}

现在它起作用了。:-)在 Coliru 上看到它


一个稍微更多或更好的通用方法是另外删除 cv限定符。最后,您可能想使用std::decay

#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
{return name<std::decay_t<decltype(args)>...>;}
于 2016-10-09T15:58:50.047 回答
1
template<class T>struct tag_t{using type=T; constexpr tag_t(){}};
template<class Tag>using tagged_type=typename Tag::type;
template<class T>constexpr tag_t<T> tag{};

这些有助于将类型作为值传递并解压缩它们。

#define PASS_VARIABLE_TEMPLATE(name) [](auto...args) \
                                                {return name<tagged_type<decltype(args)>...>;}

print_bool你里面做:

std::cout << h(tag<int>) << std::endl;

不知道你为什么这样做dummy=nullptr

tag作为模板可以携带不受干扰的类型。

于 2016-10-09T15:21:07.650 回答