【问题标题】:Is it possible to pass an expression containing lt or gt operators as a template parameter?是否可以将包含 lt 或 gt 运算符的表达式作为模板参数传递?
【发布时间】:2015-02-04 16:47:52
【问题描述】:

我认为以下程序格式正确:

#include <iostream>

template <bool>
void foo(){ };

int a = 4;
int b = 5;
int main(){ foo<a<b>(); }

DEMO

我这么想的原因是 (N4296::14.2/3 [temp.names]):

在名称查找 (3.4) 后发现名称是 template-nameoperator-function-idliteral operator-id 指的是一组 任何成员都是函数模板的重载函数,如果 这后面跟着一个&lt;&lt; 总是作为一个分隔符 template-argument-list 并且永远不会作为小于运算符。什么时候 解析一个template-argument-list,取第一个非嵌套的&gt; 作为结束分隔符而不是大于运算符。

在该示例中,我们可以看到foo&lt;a&lt;b&gt;() 表达式中的第一个&lt; 被视为模板参数的起点。模板参数到第一个&gt;,所以a&lt;b 应该被认为只是一个参数。但不是,怎么了?

【问题讨论】:

  • bool n=(a&lt;b); foo&lt;n&gt;();?
  • @ForceBru 问题不在于如何修复要工作的代码,而在于理解为什么一个代码不工作。
  • 或者只是foo&lt;(a&lt;b)&gt;();,但我认为OP正在询问他尝试的语法是不允许的规则。这与解析 vector&lt;vector&lt;int&gt;&gt; 之类的内容有关,但我不知道确切的规则。
  • 啊。是的,正如许多人现在已经注意到的那样,这些根本不是编译时常量,因此不能用作模板参数。我第一次没有注意到。

标签: c++ templates


【解决方案1】:

是的,这是可能的,只要表达式是编译时常量表达式。

您需要做的就是将您的int 设置为constexpr。您可能希望为代码的人类读者在表达式周围添加括号(编译器可以正确解析foo&lt;a&lt;b&gt;,而人类会认为最后缺少&gt;):

constexpr int a = 4;
constexpr int b = 5;
int main(){ foo<(a<b)>(); return 0;}

Demo.

【讨论】:

    【解决方案2】:

    a&lt;b 仅当 ab 都是编译时间常数时才是编译时间常数。

    这对我有用:

    #include <iostream>
    
    template <bool>
    void foo(){ };
    
    const int a = 4;
    const int b = 5;
    int main(){ foo<a<b>();}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-23
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 2019-11-30
      • 2021-02-15
      • 2021-10-20
      相关资源
      最近更新 更多