【问题标题】:sfinae vs concepts with non type template parmssfinae 与具有非类型模板参数的概念
【发布时间】:2022-01-22 09:06:39
【问题描述】:

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

可以这样做:

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; }

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

【问题讨论】:

  • requires 范围不代表条件,但它检查语句是否正在编译。所以requires { !(N % 2); }; 没有达到你的预期。
  • @MarekR:你是对的......但仍然不能将概念用于非模板参数......还是有可能的技巧?
  • 作为一个不相关的评论,我很确定你可以做到template&lt;typename T&gt;constexpr bool is_odd(T num) { return num % 2 };,不需要3个函数(c++11及更高版本,但你已经使用constexpr

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


【解决方案1】:

经过更多的实验工作,我发现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

【讨论】:

  • "我在阅读的文档中没有找到任何相关内容。" 嗯,是的。概念是template,因此它采用模板参数。第一个参数是类型can be used in special places 的概念,但这是围绕概念的模板性质的唯一特殊情况(那个和那个you cannot constrain a concept definition itself)。
  • 旁注,你好像倒了奇偶
  • 另外,不建议使用 ODD 和 !ODD,因为它很容易更改。你可以有一个默认的检查和一个专业化的偶数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多