C++11 constexpr function's argument passed in template argument

后端 未结 4 1174
深忆病人
深忆病人 2020-12-17 14:13

This used to work some weeks ago:

template 
T            tfunc()
{
    return t + 10;
}

template 
constexpr T               


        
4条回答
  •  轮回少年
    2020-12-17 14:45

    I get the feeling that constexpr must also be valid in a 'runtime' context, not just at compile-time. Marking a function as constexpr encourages the compiler to try to evaluate it at compile-time, but the function must still have a valid run-time implementation.

    In practice, this means that the compiler doesn't know how to implement this function at runtime:

    template 
    constexpr T       func(T t)
    {
        return tfunc();
    }
    

    A workaround is to change the constructor such that it takes its t parameter as a normal parameter, not as a template parameter, and mark the constructor as constexpr:

    template 
    constexpr T       tfunc(T t)
    {
        return t + 10;
    }
    template 
    constexpr T       func(T t)
    {
        return tfunc(t);
    }
    

    There are three levels of 'constant-expression-ness':

    1. template int parameter, or (non-VLA) array size // Something that must be a constant-expression
    2. constexpr // Something that may be a constant-expression
    3. non-constant-expression

    You can't really convert items that are low in that list into something that is high in that list, but obviously the other route it possible.

    For example, a call to this function

    constexpr int foo(int x) { return x+1; }
    

    isn't necessarily a constant-expression.

    // g++-4.6 used in these few lines. ideone doesn't like this code. I don't know why
    int array[foo(3)]; // this is OK
    int c = getchar();
    int array[foo(c)]; // this will not compile (without VLAs)
    

    So the return value from a constexpr function is a constant expression only if all the parameters, and the implementation of the function, can be completed at executed at compile-time.

提交回复
热议问题