c++ 如何用std::enable_if约束类模板和数据成员

tgabmvqs  于 2023-07-01  发布在  其他
关注(0)|答案(4)|浏览(151)

我有一个类模板:

template<int a, int b>
class foo {
};

我只想在a + b == 10时示例化它。我可以使用std::enable_if实现这一点吗?
此外,如果我在class foo中有一个数据成员:

template<int a, int b>
class foo {
    int c;
};

我只想有ca == 5
如何使用std::enable_if实现这一点?这是使用std::enable_if的正确情况吗?

f5emj3cl

f5emj3cl1#

template<int a, int b, typename T = typename std::enable_if<a + b == 10>::type>
class foo {
};

这应该可以了只是要确保在示例化模板时永远不要显式地提供第三个模板参数。
正如其他人提到的,static_assert是一个更好的选择。

0aydgbwb

0aydgbwb2#

我猜您可以使用static_assert而不是enable_if更好地强制执行该约束

template<int a, int b>
class foo {
    static_assert(a+b==10, "a+b is not 10");
};

int main()
{
    foo<5,5> f; // will compile
    foo<1,5> f; // will fail to compile with error: a+b is not 10
    return 0;
}

enable_if主要用于根据类型特征从重载解析中有条件地移除函数和类,并为不同的类型特征提供单独的函数重载和专门化。

wbrvyc0a

wbrvyc0a3#

使用C++20

你可以通过简单地将 requires 添加到模板中来实现:

template<int a, int b> requires (a + b == 10)
struct foo {
    int c;
};

int main() {
    foo<3, 7> ok;
    // foo<3, 8> doesnt_compile;
}
  • requires* 子句得到一个constant expression,它的计算结果是truefalse,从而决定是否将其视为正确的匹配,如果requires子句为true,则忽略它。

产品编号:https://godbolt.org/z/yHh4Et

xxls0lw8

xxls0lw84#

很简单,就是不要使用enable_if

template<bool Ten>
struct Base
{
    int c;
};

template<>
struct Base<false>
{ };

template<int a, int b>
struct foo : Base<a+b == 10>
{
};

相关问题