【问题标题】:Why can not I use constexpr value in function, but I can do the same in scope of this value?为什么我不能在函数中使用 constexpr 值,但我可以在这个值的范围内做同样的事情?
【发布时间】:2016-12-20 13:55:34
【问题描述】:

我不能在函数中使用 constexpr 值,而不是在函数之外。

  • 我可以在定义了il 的范围内使用auto ar1 = std::array<int, il.size()>();

  • 但是我不能在constexpr-function il_to_array()中使用{ return std::array<T, il.size()>();}

为什么我不能在函数中使用 constexpr 值,但我可以在这个值的块范围内做同样的事情?

http://ideone.com/5g0iRE

#include <iostream>
#include <initializer_list>
#include <array>

constexpr size_t size_to_size(size_t v) { return v; }   // 1 - OK

template<typename T>
constexpr size_t il_to_size(std::initializer_list<T> il) { return il.size(); }  // 2 - OK

// 3 - error
template<typename T>
constexpr auto il_to_array(std::initializer_list<T> il) {return std::array<T, il.size()>();}

template<size_t N>
void print_constexpr() { std::cout << N << std::endl; }

int main() {

    constexpr std::initializer_list<int> il = { 1, 2, 3 };
    print_constexpr<il.size()>();   // 0 - OK

    print_constexpr< size_to_size(il.size()) >();   // 1 - OK

    print_constexpr< il_to_size(il) >();    // 2 - OK

    auto ar1 = std::array<int, il.size()>();    // OK - body of function: il_to_array()

    //auto ar2 = il_to_array(il);   // 3 - error

    return 0;
}

例如,我们看到,template-constexpr-function 不会失败,即使它可能是也可能不是 constexpr - 取决于 T,因为实例之一可能是 constexprWhy does the C++ compiler makes it possible to declare a function as constexpr, which can not be constexpr?

  • 并且可以得出结论,如果这是一个模板函数,它可能是以下任一特化:constexpr 和非constexpr

  • 并且在SFINAE的基础上——如果我们只使用constexpr-arguments那么只实例化constexpr-instance,非constexpr-function不能实例化也没关系.

【问题讨论】:

    标签: c++ c++11 c++14 constexpr compile-time


    【解决方案1】:

    (constexpr) 函数的参数不是constexpr

    constexpr 函数可能会被赋予编译时未知的参数。

    所以无论v在编译时是否已知,以下都是有效的

    constexpr size_t size_to_size(size_t v) { return v; }
    

    但以下函数不起作用,因为 il 不是 constexpr 并且非类型模板参数需要在编译时知道:

    template<typename T>
    constexpr auto il_to_array(std::initializer_list<T> il) {return std::array<T, il.size()>();}
    

    即使只使用编译时已知的参数调用函数也是如此。

    【讨论】:

    • Err...我不确定故事是否会因为 OP 的困境而结束...ClangMSVC 无法编译 OP 的代码(只有 gcc 可以)。他们拒绝它,因为他们不考虑创建std::initializer_list&lt;int&gt;constexpr.. 我相信:因为标准并不清楚它是constexpr,除了它的成员函数。另一个支持逻辑,如果T 不能在std::initializer_list&lt;T&gt; 中初始化为constexpr 怎么办?
    • @WhiZTiM:查看why-isnt-stdinitializer-list-defined-as-a-literal-type 以了解该错误。
    • 我浏览了所有链接到 forum discussion .. 根据 Richard Smith 的回复,Clang 和 MSVC 关于 constexpr std::initializer_list&lt;int&gt; il = {1,2,3,4}; 格式错误的说法是正确的。
    猜你喜欢
    • 1970-01-01
    • 2020-09-08
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多