C++0x error with constexpr and returning template function

▼魔方 西西 提交于 2019-12-01 03:17:00

Since constexpr should guarantee that a function only contains compile time constants, and is evaluated at compile time (at least thats what i think it does), i thought it might be the solution for this issue.

A constexpr function can be used in a constant expression context, but is not restricted to one. In this respect they are different from a metafunction and a regular function. Consider the problem of returning the successor of an integer:

// Regular function
int f(int i)
{ return i + 1; }

// Regular metafunction
template<int I>
struct g {
    static constexpr auto value = I + 1;
};

// constexpr function
constexpr int h(int i)
{ return i + 1; }

// Then...
{
    // runtime context: the metafunction can't be used
    int i;
    std::cin >> i;

    f(i); // Okay
    g<i>::value; // Invalid
    h(i); // Okay

    // compile time context: the regular function can't be used
    char a[f(42)]; // Invalid
    char b[g<42>::value]; // Okay
    char c[h(42)]; // Okay
}

constexpr has other usages (e.g. constructors) but when it comes to constexpr functions this is the gist of it: some functions should be available in both runtime and constant contexts because some computations are available in both. It's possible to compute i + 1 whether i is a compile-time constant or is extracted from std::cin.

This means that inside the body of a constexpr function the parameters are not themselves constant expressions. So what you are attempting is not possible. Your function can't deal with

int i;
std::cin >> i;
get_f(i); // what's the return type?

and the violation happens here:

constexpr auto get_f(T t)
-> decltype( &f<T,t> ) // <-

Since t is not a constant expression according to the rules of the language (no matter what, even if you actually only pass constant expressions in), it can't appear as the second template parameter of f.

(And in the larger picture it means that no, you can't use argument deduction from function templates to conveniently pass a non-type parameter to a class template.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!