C++ C++;实现我自己的静态断言
作为一个学习项目,我正在编写自己的模板元编程静态断言。我在网上发现了一个元编程技巧:尝试创建一个大小为0的数组,它将无法编译。所以我使用了两种几乎相同的方法:在VisualStudio上,一种工作,另一种不工作,但我不明白有什么区别。在g++5.4.0上,两者都不起作用(即使使用“-std=c++14”标志也不起作用)。为什么不呢C++ C++;实现我自己的静态断言,c++,c++11,templates,static-assert,C++,C++11,Templates,Static Assert,作为一个学习项目,我正在编写自己的模板元编程静态断言。我在网上发现了一个元编程技巧:尝试创建一个大小为0的数组,它将无法编译。所以我使用了两种几乎相同的方法:在VisualStudio上,一种工作,另一种不工作,但我不明白有什么区别。在g++5.4.0上,两者都不起作用(即使使用“-std=c++14”标志也不起作用)。为什么不呢 //This correctly aborts the compile on Visual Studio 2015. //But on g++ it doesn't
//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???
}
//这将正确中止Visual Studio 2015上的编译。
//但在g++上它不起作用(即使使用“-std=c++14”标志也不行)。
模板
内联void my_static_assert_函数()
{
char成员[b];//如果b为false,则表示长度为0且无法编译。
}
//在Visual Studio 2015上,这确实会发出警告,但不会
//中止编译。为什么不呢?它似乎与
//上一个。在g++上,它甚至没有警告。
模板
struct my\u static\u assert\u struct
{
char成员[b];//如果b为false,则此*警告*但编译。
};
int main()
{
my_static_assert_function();//这会中止编译,太好了。
my_static_assert_struct c;//这不会中止编译???
}
问题#1——为什么“g++-std=c++14 main.cpp”允许在没有警告的情况下编译它?my_static_assert_函数不应该在那里工作吗?我在ubuntu上使用5.4.0
问题#2——在Visual Studio 2015上,我的_static_assert_函数无法编译,但我的_static_assert_结构编译时只发出一个警告。但是有什么不同呢?如果一个不工作,另一个怎么能工作 > P> > @ KeRek SB在评论中提到的,
false
via,就像这样
GCC是一只狡猾的野兽。你真的需要学习它的所有标志,才能把它变成一个诚实的编译器。(这就是为什么真正的程序员会制作大小为-1的数组。)@Kerrek SB:直到GCC也找到了在扩展中生成的理由。
char成员[b?1:-1]代码>静态断言的两个主要目的是:(1)在任何允许的地方都能在所有编译器上一致工作。(2) 有用的错误消息。
#include <iostream>
#include <type_traits>
template<bool b, typename std::enable_if<b>::type* = nullptr>
void my_static_assert()
{
std::cout << "Assertion OK\n";
}
int main()
{
my_static_assert < (1 < 2) > (); // ok
//my_static_assert < (1 > 2) > (); // fails to compile
}
template<bool> // generic
struct my_static_assert;
template<>
struct my_static_assert<true>{};
int main()
{
my_static_assert < (1 < 2) >{}; // ok
my_static_assert < (1 > 2) >{}; // fails to compile
}