rcv*_*rcv 31 c++ initializer-list constexpr c++11
为什么st_ :: initializer_list <_E> :: size在static_assert中是不允许的,即使它在我的libstdc ++(v.4.6)中被声明为constexpr?
例如,以下代码:
template<class T, int Length>
class Point
{
public:
Point(std::initializer_list<T> init)
{
static_assert(init.size() == Length, "Wrong number of dimensions");
}
};
int main()
{
Point<int, 3> q({1,2,3});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
test.C: In constructor ‘Point<T, Length>::Point(std::initializer_list<_Tp>) [with T = int, int Length = 3]’:
test.C:60:26: instantiated from here
test.C:54:7: error: non-constant condition for static assertion
test.C:54:73: in constexpr expansion of ‘init.std::initializer_list<_E>::size [with _E = int, std::initializer_list<_E>::size_type = long unsigned int]()’
test.C:54:7: error: ‘init’ is not a constant expression
Run Code Online (Sandbox Code Playgroud)
请注意,这适用于一个简单的示例:
class A
{
public:
constexpr int size() { return 5; }
};
int main()
{
A a;
static_assert(a.size() == 4, "oh no!");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
ale*_*cov 20
"初始化列表"只是可怕的克拉格.
别:
#include <initializer_list>
template<typename T>
void Dont(std::initializer_list<T> list) { // Bad!
static_assert(list.size() == 3, "Exactly three elements are required.");
}
void Test() { Dont({1,2,3}); }
Run Code Online (Sandbox Code Playgroud)
做:
template<typename T, std::size_t N>
void Do(const T(&list)[N]) { // Good!
static_assert(N == 3, "Exactly three elements are required.");
}
void Test() { Do({1,2,3}); }
Run Code Online (Sandbox Code Playgroud)
Bo *_*son 11
编译器说init是问题,而不是init.size().
我猜可以从具有不同长度初始化器的不同位置调用构造函数.
(详细说明:你试图写一个static_assert
取决于变量的运行时值init
,即它有多少元素.static_assert
在编译函数时必须可以计算.你的代码类似于这个无效的例子:)
void foo(int i) { static_assert(i == 42, ""); }
int main() { foo(42); } // but what if there's a caller in another translation unit?
Run Code Online (Sandbox Code Playgroud)
从我与@Evgeny 的讨论中,我意识到这仅适用于(与gcc 4.8 c++11
),并且也可以通过仅接受初始化列表(在main
)中的兼容大小来进行大小检查。
(代码链接:http : //coliru.stacked-crooked.com/a/746e0ae99c518cd6)
#include<array>
template<class T, int Length>
class Point
{
public:
Point(std::array<T, Length> init)
{
//not needed// static_assert(init.size() == Length, "Wrong number of dimensions");
}
};
int main()
{
Point<int, 3> q({1,2,3}); //ok
// Point<int, 3> q2({1,2,3,4}); //compile error (good!)
Point<int, 3> q2({1,2}); // ok, compiles, same as {1,2,0}, feature or bug?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9640 次 |
最近记录: |