I was toying a little bit with the indices trick to see where I could go to with and came across a strange error... First, the plain not-so-old indices:
我有点玩弄指数技巧,想看看我能做什么,却发现了一个奇怪的错误……首先,不那么古老的指数:
template<std::size_t...>
struct indices {};
template<std::size_t N, std::size_t... Indices>
struct make_indices:
make_indices<N-1, N-1, Indices...>
{};
template<std::size_t... Indices>
struct make_indices<0, Indices...>:
indices<Indices...>
{};
I created a compile-time array class derived from a std::initializer_list
and had it indexable (assume that N3471 is support by your compiler. It will be in the next standard anyway). Here it is:
我创建了一个从std:::initializer_list派生的编译时数组类,并使它具有可索引性(假设N3471是由编译器支持的)。无论如何,它将是下一个标准)。这里是:
template<typename T>
struct array:
public std::initializer_list<T>
{
constexpr array(std::initializer_list<T> values):
std::initializer_list<T>(values)
{}
constexpr auto operator[](std::size_t n)
-> T
{
return this->begin()[n];
}
};
So, I tried to create a function that returns a copy of an array
after having added 1 to each of its members:
因此,我尝试创建一个函数,在向每个成员添加1之后返回一个数组的副本:
template<typename T, std::size_t... I>
auto constexpr add_one(const array<T>& a, indices<I...>)
-> const array<T>
{
return { (a[I]+1)... };
}
And to finish with the code, here is my main:
最后,我想说的是:
int main()
{
constexpr array<int> a = { 1, 2, 3 };
constexpr auto b = add_one(a, make_indices<a.size()>());
return 0;
}
I did not think that code would compile anyway, but I am quite surprised by the error message (Here is the ideone code):
我不认为代码会被编译,但是我对错误消息感到非常惊讶(这里是ideone代码):
In function 'int main()':
error: 'const smath::array<int>{std::initializer_list<int>{((const int*)(& const int [3]{2, 3, 4})), 3u}}' is not a constant expression
So, could someone explain to me what exactly is not constant enough for the compiler in the above code?
那么,谁能向我解释一下上面代码中什么是不足够的常量?
EDIT: Follow-ups for that question
编辑:关于这个问题的后续报道。
- Is it legal to declare a constexpr std::initializer_list object?
- 声明constexpr std::initializer_list对象合法吗?
- Confusion about constant expression
- 常数表达式感到困惑
1 个解决方案
#1
1
From: the man himself http://www.stroustrup.com/sac10-constexpr.pdf
出处:该男子本人http://www.stroustrup.com/sac10-constexpr.pdf
Specifically: its return type, and the types of its parameters (if any), are literal types (see x2.2). For concreteness, literal types include bool, int, or double; its body is a compound statement of the form { return expr; } where expr is such that if arbitrary constant expressions of appropriate types are substituted for the parameters in expr, then the resulting expression is a constant expression as defined in introductory paragraph of x2. The expression expr is called a potential constant expression.
具体地说:它的返回类型和它的参数类型(如果有的话)是文字类型(参见x2.2)。具体来说,文字类型包括bool、int或double;它的主体是格式{return expr的复合语句;在expr中,如果将适当类型的任意常数表达式替换为expr中的参数,那么得到的表达式就是在x2的引言段中定义的常量表达式。表达式expr称为势常数表达式。
#1
1
From: the man himself http://www.stroustrup.com/sac10-constexpr.pdf
出处:该男子本人http://www.stroustrup.com/sac10-constexpr.pdf
Specifically: its return type, and the types of its parameters (if any), are literal types (see x2.2). For concreteness, literal types include bool, int, or double; its body is a compound statement of the form { return expr; } where expr is such that if arbitrary constant expressions of appropriate types are substituted for the parameters in expr, then the resulting expression is a constant expression as defined in introductory paragraph of x2. The expression expr is called a potential constant expression.
具体地说:它的返回类型和它的参数类型(如果有的话)是文字类型(参见x2.2)。具体来说,文字类型包括bool、int或double;它的主体是格式{return expr的复合语句;在expr中,如果将适当类型的任意常数表达式替换为expr中的参数,那么得到的表达式就是在x2的引言段中定义的常量表达式。表达式expr称为势常数表达式。