我知道如何pass template function as template argument,我现在正在努力以类似的方式传递变量模板。
这是我尝试过的最小例子:
#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
}
如果编译,那么输出错误的原因是什么?
答案 0 :(得分:3)
The main problem with your code is that decltype
deduces the arguments as an rvalue
reference (int&&
) because your lambda uses forwarding references to accept the arguments.
std::is_fundamental
will work well with a bare type.
For your specific snippet, the correct solution is to remove the reference.
#define PASS_VARIABLE_TEMPLATE(name) \
[dummy=nullptr](auto&&...args){return name<std::remove_reference_t<decltype(args)>...>;}
Now it works. :-) See it Live On Coliru
A slightly more or better generic way will be to additionally remove cv qualifiers. In the end, you may want to use std::decay
#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
{return name<std::decay_t<decltype(args)>...>;}
答案 1 :(得分: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
作为模板可以进行未受干扰的类型。