c++ - 用作函数参数时如何定义转换为类模板工作
问题描述
有这个模板:
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'
我试着以某种方式f
说X
默认情况下false
,但f
(我的意思是编译器)不听我的:
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>)
*/
}
我不介意引入一些额外的辅助类等。我希望也许一些decltype
,auto
或some_trait<>
额外的辅助类 (/es) 魔法可以帮助解决这个问题,我想我也可以总结为:如何定义一个功能推导指南?
解决方案
问题template <bool X = false> void f(Foo<X> foo)
在于,在将参数传递给模板参数推导中使用的参数时,不允许进行隐式转换。
您可以添加f
接受的额外重载int
,或者根本不制作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) {...}
这意味着布尔值不再constexpr
位于f
. 如果你想要它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{});
}
推荐阅读
- ios - dyld:库未加载:@rpath/Alamofire.framework/Alamofire 图像未找到
- android - 单击回收器适配器、Kotlin、Android Studio 中的单元格时显示进度条
- javascript - Firebase Storage Nodejs 如何在控制台中显示 url Public PDF Files
- linux - 颤振运行无休止运行Gradle任务'assembleDebug'
- java - 将 C 转换为 Java
- reactjs - ReactJS cors“'Access-Control-Allow-Origin'标头包含多个值”
- django - django-celery-beat 和 DatabaseScheduler 具有设置的首次运行时间
- python - Tensorflow - 将张量扩展到 3D 的更好方法
- .net - Wix - 无法重新编译从 MSI 反转的 WXS - ICE68:操作的自定义操作类型无效
- c# - 当我停止触摸虚拟操纵杆时,是否有停止播放器的方法?