我试图基于一个完整的类模板参数启用不同的成员函数,如下所示:
#include <type_traits>
template<int Dimension>
struct Foo
{
template<std::enable_if_t<Dimension == 1> = 0>
int bar(int i) const { return i; }
template<std::enable_if_t<Dimension == 2> = 0>
int bar(int i, int j) const { return i + j; }
};
int main(int argc, const char **argv)
{
Foo<1> a;
a.bar(1);
Foo<2> b;
b.bar(1,2);
return 0;
}
在c ++-14模式下使用gcc5,它无法编译并出现以下错误:
tools/t1.cpp: In instantiation of 'struct Foo<1>':
tools/t1.cpp:18:12: required from here
tools/t1.cpp:13:9: error: no type named 'type' in 'struct std::enable_if<false, int>'
int bar(int i, int j) const { return i + j; }
^
tools/t1.cpp: In instantiation of 'struct Foo<2>':
tools/t1.cpp:21:12: required from here
tools/t1.cpp:10:9: error: no type named 'type' in 'struct std::enable_if<false, int>'
int bar(int i) const { return i; }
这些似乎表明SFINAE并没有达到我的期望,因为enable_if_t似乎工作正常。
在这个简单的示例中,重载也可以工作,但是在我的实际用例中,我需要根据情况隐藏函数以防止意外使用和/或编译错误。
我在这里与SFINAE缺少什么?
当模板参数推论发生时,替代失败不是一件容易的事。
另外,enable_if_t<true>
是void
,并且您不能具有void
模板非类型参数。
使用默认模板参数推迟评估:
template<int Dimension>
struct Foo
{
template<int..., int I = Dimension, std::enable_if_t<I == 1, int> = 0>
int bar(int i) const { return i; }
// etc.
};
未命名的参数包int...
可防止尝试显式指定I
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句