如何定义在用作函数参数时工作的类模板的转换

How to define conversion to class template working when used as function argument

本文关键字:工作 参数 转换 函数 何定义 定义      更新时间:2023-10-16

拥有此模板:

template <bool X> 
struct Foo {
Foo(int v) : v(v) {}
int v;
};

我可以说默认情况下,Foo应该与扣除指南False

Foo(int)->Foo<false>;

感谢这段代码的工作:

Foo a = 5;

我的问题是,当Foo用作函数参数时,我如何才能使这项工作:

template <bool X> 
void f(Foo<X> foo) { 
cout << "Foo<" << X << ">(" << foo.v << ")" << endl; 
}
f(5); // error: no matching function for call to 'f'
// candidate template ignored: could not match 'Foo<X>' against 'int'

我试着以某种方式说fX是默认的falsef(我的意思是编译器(没有听我的话:

template <bool X = false> // = false changes nothing, same error 
void f(Foo<X> foo) {
cout << "Foo<" << X << ">(" << foo.v << ")" << endl; 
}
template <bool X> 
struct get_bool { // to force looking at f::X 
static constexpr bool value = X; 
};
template <bool X = false> 
void f(Foo<get_bool<X>::value> foo) { 
cout << "Foo<" << X << ">(" << foo.v << ")" << endl;         
/* this is not working because 
* get_bool evaulates before 
* args matching and in the end, 
* this function could be defined 
* as: void f(Foo<false>) 
*/
}

我不介意引入一些额外的帮助程序类等。 我希望也许一些decltypeautosome_trait<>或其他辅助类(/es(魔法可以帮助解决这个问题,我想我也可以总结为: 如何定义函数的演绎指南?

template <bool X = false> void f(Foo<X> foo)的问题在于,将参数传递给模板参数推导中使用的参数时,不允许隐式转换。

您可以在接受int时添加额外的重载f,或者根本不f模板:

struct Bar
{
bool x = false;
int v = 0;
template <bool X>
Bar(Foo<X> foo) : x(X), v(foo) {}
Bar(int v) : v(v) {}
};
void f(Bar bar) {...}

这意味着布尔值不再constexprf内部。如果你想让它constexpr,你可以使用一个技巧:

void f(Bar bar)
{
auto lambda = [&](auto x_value)
{
constexpr bool x = x_value;
// Here `x` is `constexpr`.
};
if (bar.x)
lambda(std::true_type{});
else
lambda(std::false_type{});
}