【问题标题】:Using function return value as default template non-type parameter使用函数返回值作为默认模板非类型参数
【发布时间】:2015-07-24 00:37:45
【问题描述】:

这是我的代码:

bool test(){
    return true;
}


template<int asd[], bool T = test()>
void evenprocessor(){
    std::cout<<"this is called"<<std::endl;
};

int asd[] = {1,2,3};

int main(int argc, char** argv) {
    evenprocessor<asd>();
    return 0;
}

我正在为 sfinae 做一些测试,我很好奇这样的事情是否可能。调用模板后评估函数。我收到一条错误消息,指出 没有匹配的函数可以调用 evenprocessor

如果在函数或模板参数中使用函数,我是不是做错了什么或者无法评估函数?像这样的:

template<int asd[]>
void evenprocessor(char(*)[test()]){
    std::cout<<"this is called"<<std::endl;
};

int asd[] = {1,2,3};

int main(int argc, char** argv) {
    evenprocessor<asd>();
    return 0;
}

我收到一条错误消息,指出 variable or field evenprocessor declared void。为什么它被宣布为无效?

【问题讨论】:

  • 你可能错过了constexprconstexpr bool test() { return true;}
  • 模板用于传递类型信息或计数。您正在传递变量。你能解释一下为什么非模板版本(即: void evenprocessor(int*) )不适合你吗?
  • 用于测试/教育目的并了解他们的行为。
  • 你在做什么没有任何意义。您使用模板传递类型信息。在您的示例中,您试图传递一个变量。这不是模板的用途。
  • 使用 Clang:template argument deduction/substitution failed: call to non-constexpr function 'bool test()'。使用constexpr 可以正常工作。

标签: c++ templates c++11


【解决方案1】:

第一个没有为我编译。我不得不把它改成这个,为 C++11 编译。将test() 函数声明为constexpr,让编译器知道它可以在编译时进行评估。

调用模板后评估函数。

您需要确保可以在编译时评估函数,如前所述。否则无法编译程序。

#include <iostream>

constexpr bool test(){
        return true;
}


template<int asd[], bool T = test()>
                             void evenprocessor(){
        std::cout << "this is called" << std::endl;
};

int asd[] = {1,2,3};

int main(int argc, char** argv) {
        evenprocessor<asd>();
        return 0;
}

第二个代码示例对我来说没有意义。你想达到什么目的?

我看到了几个错误。

  • 参数名称不存在。
  • 函数运算符括号中的代码应该是一个 lambda 函数。您可能试图实现的是指向一个数组,该数组包含一个类型为bool 且值为true 的元素。查看您的要求。

【讨论】:

    【解决方案2】:

    模板非类型参数必须是转换后的常量表达式。函数的调用“除了 constexpr 文字类的构造函数、constexpr 函数或普通析构函数的隐式调用”不是核心常量表达式([expr.常量])。在您的演员阵容中,test() not 是核心常量表达式,因为它 not constexpr。编译错误非常清楚地表明了这一点:

    clang 的错误:

    main.cpp:8:30: error: non-type template argument is not a constant expression
    template<int asd[], bool T = test()>
                                 ^~~~~~
    

    gcc 的错误:

    main.cpp:9:6: note:   template argument deduction/substitution failed:
    main.cpp:8:34: error: call to non-constexpr function 'bool test()'
     template<int asd[], bool T = test()>
                                      ^
    

    只需修复test:

    constexpr bool test() {
        return true;
    }
    

    第二个例子由于同样的原因失败了。数组边界也必须是核心常量表达式。如果您将test() 固定为constexpr,那么您的代码将失败,原因很明显:

    main.cpp:16:5: error: no matching function for call to 'evenprocessor'
        evenprocessor<asd>();
        ^~~~~~~~~~~~~~~~~~
    main.cpp:9:6: note: candidate function template not viable: requires 1 argument, but 0 were provided
    void evenprocessor(char(*)[test()]){
         ^
    

    哦,对了,必须传递一些东西:

    evenprocessor<asd>(nullptr);
    

    现在一切都编译好了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-23
      • 2016-11-09
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多