为什么这不是一个常数表达式? [英] Why is this not a constant expression?

查看:1260
本文介绍了为什么这不是一个常数表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个简单的例子中, test2 无法编译,即使 test1 成功,我不明白为什么就是这种情况。如果 arr [i] 适用于标记为 constexpr 的函数的返回值,那么为什么它不能用作一个非类型的模板参数?

In this trivial example, test2 fails to compile even though test1 succeeds, and I don't see why that is the case. If arr[i] is suitable for a return value from a function marked constexpr then why can it not be used as a non-type template argument?

template<char c>
struct t
{ 
    static const char value = c;
};

template <unsigned N>
constexpr char test1(const char (&arr)[N], unsigned i)
{
    return arr[i];
}

template <unsigned N>
constexpr char test2(const char (&arr)[N], unsigned i)
{
    return t<arr[i]>::value;
}

int main()
{
   char a = test1("Test", 0); //Compiles OK
   char b = test2("Test", 0); //error: non-type template argument 
                              //is not a constant expression
}


$ b b

编辑:这没有区别:

This makes no difference:

template<char c>
struct t
{ 
    static const char value = c;
};

template <unsigned N>
constexpr char test1(const char (&arr)[N])
{
    return arr[0];
}

template <unsigned N>
constexpr char test2(const char (&arr)[N])
{
    return t<arr[0]>::value;
}

int main()
{
   char a = test1("Test"); //Compiles OK
   char b = test2("Test"); //error: non-type template argument 
                           //is not a constant expression
}


推荐答案

简短的答案: C ++ 11/14中没有 constexpr / code>。

Short answer: there are no constexpr function parameters in C++11/14.

更长的答案:在 test1() i 不是编译时常量,该函数在运行时仍然可用。但在 test2()中,编译器不能知道 i 是否是编译时常量,它需要函数来编译。

Longer answer: in test1(), if i is not a compile-time constant, the function is still usable at run-time. But in test2(), it cannot be known to the compiler whether i is a compile-time constant, and yet it is required for the function to compile.

例如以下代码 test1 将编译

int i = 0;    
char a = test1("Test", i); // OK, runtime invocation of test1()

constexpr int i = 0;
constexpr char a = test1("Test", i); // also OK, compile time invocation of test1()

test2()到

Let's simply your test2() to

constexpr char test3(unsigned i)
{
    return t<i>::value;
}

这不会编译 test3 / code>因为 test3()内部不能证明 i 无条件编译时表达式。您将需要 constexpr 函数参数才能表达。

This will not compile for test3(0) because inside test3(), it cannot be proven that i is an unconditional compile-time expression. You would need constexpr function parameters to be able to express that.

5.19常量表达式[expr.const]


- 表达式e是一个核心常量表达式,除非对e的
求值遵循抽象机(1.9),
的规则将评估下列表达式之一:

2 A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

- 引用
引用类型的变量或数据成员的id表达式,除非引用具有先前的初始化,并且


- 它已初始化具有常量表达式或

— an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
— it is initialized with a constant expression or

- 它是对象的非静态数据成员,其生命周期在e的评估中开始;

— it is a non-static data member of an object whose lifetime began within the evaluation of e;

此部分具有与您的问题对应的以下代码示例:

This section has the following code example corresponding to your question:

constexpr int f1(int k) {
    constexpr int x = k; // error: x is not initialized by a
                         // constant expression because lifetime of k
                         // began outside the initializer of x
    return x;
}

因为 x 上面的例子不是一个常量表达式,这意味着你不能使用 x k f1

Because x in the above example is not a constant expression, it means that you can't instantiate templates with either x or k inside f1.

这篇关于为什么这不是一个常数表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆