Why is this not a constant expression?

后端 未结 4 1282
广开言路
广开言路 2021-01-01 12:21

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 suitab

4条回答
  •  借酒劲吻你
    2021-01-01 13:14

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

    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.

    E.g. the following code for test1 will compile

    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()
    

    Let's simply your test2() to

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

    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.

    Quote from the Standard

    5.19 Constant expressions [expr.const]

    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:

    — 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

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

    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.

提交回复
热议问题