Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;实现我自己的静态断言_C++_C++11_Templates_Static Assert - Fatal编程技术网

C++ C++;实现我自己的静态断言

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

作为一个学习项目,我正在编写自己的模板元编程静态断言。我在网上发现了一个元编程技巧:尝试创建一个大小为0的数组,它将无法编译。所以我使用了两种几乎相同的方法:在VisualStudio上,一种工作,另一种不工作,但我不明白有什么区别。在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???
}
//这将正确中止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在评论中提到的, GCC 使用一些非标准的ISO C++扩展,允许零大小的数组,尽管它会给您一个警告。一个更为优雅的选择是out
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
}