c++ - sfinae 与非类型模板参数的概念

标签 c++ c++20 sfinae c++-concepts non-type-template-parameter

出于学术原因,我想实现一个示例,如果非类型模板参数满足给定条件,则选择一个模板。例如,我想要一个只为奇数定义的函数。

可以这样做:

template < int N, bool C = N%2>
struct is_odd: public std::false_type{};
template<int N > 
struct is_odd< N,true >: std::true_type{};

template < int N>
constexpr bool is_odd_v = is_odd<N>::value;

template < int N, typename T=typename std::enable_if_t<is_odd_v<N>, int> >
void Check(){ std::cout << "odd number template specialization " << std::endl; };

int main()
{
   Check<1>();
   Check<2>(); // fails, as expected, ok
}

我认为做这么简单的事情需要很多代码。很清楚,我可以直接在 std::enable_if 中使用取模运算,但假设将对非类型模板参数值进行更复杂的检查。

问:这是否可以在没有这么多间接步骤的情况下完成,但仍然有一些 std::is_xxx 在使用中?

顺便说一句:如果 concepts 可以处理非类型模板参数,它可以做得更简单,但我知道,不是为它设计的......

template < int N >
concept ODD = !(N % 2); 

template < ODD N >
void Check() { std::cout << "odd number template specialization " << std::endl; }

奖励:也许有人知道为什么不为非类型模板参数创建概念?

最佳答案

经过更多的实验工作后,我发现 concepts 可用于非类型模板参数。我在阅读的文档中根本没有找到任何相关内容。

template < int I > 
concept ODD = !(I%2);

template< int N > 
requires( ODD<N> )
void Check() { std::cout << "odd number template spezialisation " << std::endl; }

template< int N > 
requires( !ODD<N> )
void Check() { std::cout << "even number template spezialisation " << std::endl; }

int main()
{
    Check<2>();
    Check<4>();
    Check<3>();
}

Live demo

关于c++ - sfinae 与非类型模板参数的概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70427057/

相关文章:

c++ - 如何更改 QTabWidget 选项卡中文本的颜色

c++ - 错误: “expression must have class type” & “left of must have class/struct/union”

c++ - 为什么std::forward_list::: remove和std::erase <std::forward_list>具有不同的值类型?

c++ - bool 表达式作为模板参数

c++ - 递归调用重载的c++函数

c++ - 尝试删除二叉树中的节点时双重释放或损坏(out)

c++ - 这段代码是线程安全的吗?

c++ - 为什么 Visual Studio 在没有优化的情况下可以正确编译此函数,但在优化时却编译错误?

c++ - 无法在带有 Clang 的模块中使用对齐的 `operator new`

c++ - SFINAE 不适用于复制构造函数