Rei*_*izo 3 c++ templates static-assert enable-if class-template
我想知道std::enable_ifoverstatic_asserts防止模板实例化的优势。这个答案表明,这std::enable_if允许SFINAE,这在函数模板的情况下是一个令人信服的论点。
然而,这个论点对于类模板(和变量模板)是否合法?据我所知,那里不涉及重载决议,这使得 SFINAE - 再次,据我所知 - 不相关,但我可能是错的。如果是这样,你能举一个例子吗?
如果不是,我认为static_assert在类模板的情况下是给定问题(防止模板实例化)的更好解决方案,因为它可以说更明确、简洁和可读,并允许自定义错误消息。这是正确的还是我错过了 SFINAE 以外的一点?
如何使用 SFINAE 重载类的示例:
#include <type_traits>
#include <iostream>
template <typename, typename = void>
struct Foo;
template <typename Bar>
struct Foo <Bar, typename std::enable_if<std::is_same<Bar,int>::value>::type>
{
Foo ()
{
std::cout << "Hello ";
}
};
template <typename Bar>
struct Foo <Bar, typename std::enable_if<std::is_same<Bar,bool>::value>::type>
{
Foo ()
{
std::cout << "world!\n";
}
};
int main()
{
Foo<int>();
Foo<bool>();
}
Run Code Online (Sandbox Code Playgroud)
对于您不想重载但仍想限制为一组类型的情况,我同意:
template <typename Bar>
class Foo
{
static_assert(
std::is_same<Bar,int>::value ||
std::is_same<Bar,bool>::value,
"Bar must be bool or int");
// class stuff
};
Run Code Online (Sandbox Code Playgroud)
...比以下内容更清晰、更简单:
template <typename Bar,
typename std::enable_if<
std::is_same<Bar,int>::value ||
std::is_same<Bar,bool>::value,
bool>::type = true>
class Foo
{
// class stuff
};
Run Code Online (Sandbox Code Playgroud)
...特别是因为使用第二个选项时,编译器Foo使用它们的第一个参数和第二个参数(true在我们的例子中)来引用对象,这对用户来说可能是神秘的。此外,如果您想要一个头文件来处理该类,并且只对其进行轻量级声明,则会更加混乱(请参阅如何在此处执行此操作)。