【发布时间】:2016-10-27 00:53:05
【问题描述】:
作为一个学习项目,我正在编写自己的模板元编程 static_assert。我在网上找到了一个元编程技巧:尝试创建一个大小为 0 的数组,这将无法编译。所以我使用了两种几乎相同的方法:在 Visual Studio 上,一种有效,另一种无效,但我不明白有什么区别。在 g++ 5.4.0 上,两者都不起作用(即使使用“-std=c++14”标志也不行)。为什么不呢?
//This correctly aborts the compile on Visual Studio 2015.
//But on g++ it doesn't work (not even with the "-std=c++14" flag) .
template <bool b>
inline void my_static_assert_function()
{
char member[b]; //if b is false, this is 0-length and fails to compile.
}
//On Visual Studio 2015, this does give a warning, but does not
//abort the compile. Why not? It seems virtually identical to the
//previous one. And on g++, it doesn't even warn.
template <bool b>
struct my_static_assert_struct
{
char member[b]; //if b is false, this *warns* but compiles.
};
int main()
{
my_static_assert_function<1 == 2>(); //This aborts the compile, great.
my_static_assert_struct<1 == 2> c; //This does NOT abort the compile???
}
问题#1——为什么“g++ -std=c++14 main.cpp”允许它在没有警告的情况下编译? my_static_assert_function 不应该在那里工作吗?我在 ubuntu 上使用 5.4.0。
问题 #2 - 在 Visual Studio 2015 上,my_static_assert_function 无法编译,但 my_static_assert_struct 编译时仅显示警告。但是有什么区别呢?如果另一个不工作,一个怎么能工作?
【问题讨论】:
-
GCC 是一个狡猾的野兽。你真的需要学习它的所有标志才能把它变成一个诚实的编译器。
-
(这就是真正的程序员制作大小为 -1 的数组的原因。)
-
@Kerrek SB:直到 GCC 也找到了扩展的理由。
-
char member[b ? 1 : -1]; -
static_assert的主要两个目的是: (1) 在允许的任何地方对所有编译器进行一致的工作。 (2) 有用的错误信息。
标签: c++ c++11 templates static-assert