Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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
为什么更喜欢基于模板的静态断言而不是基于typedef的静态断言? 有两种C++版本的静态断言,它们没有内置的代码> StistaSysTys< /C>_C++_Templates_Visual C++_Static Assert - Fatal编程技术网

为什么更喜欢基于模板的静态断言而不是基于typedef的静态断言? 有两种C++版本的静态断言,它们没有内置的代码> StistaSysTys< /C>

为什么更喜欢基于模板的静态断言而不是基于typedef的静态断言? 有两种C++版本的静态断言,它们没有内置的代码> StistaSysTys< /C>,c++,templates,visual-c++,static-assert,C++,Templates,Visual C++,Static Assert,第一个用于Boost并使用: 这里,一旦违反了要检查的条件,编译器就会尝试typedef一个大小为-1的数组,这是非法的,因此会出现编译时错误 对我来说,后者更好,因为它保证不发出任何代码,并且可以这样使用(从): 模板类二进制标志{ STATIC_ASSERT(0STATIC_ASSERT的第二个版本您不能在同一块中逐个使用 template<int N, int M> void foo () { STATIC_ASSERT(N<M), STATIC_ASSERT(M&l

第一个用于Boost并使用:

这里,一旦违反了要检查的条件,编译器就会尝试
typedef
一个大小为-1的数组,这是非法的,因此会出现编译时错误

对我来说,后者更好,因为它保证不发出任何代码,并且可以这样使用(从):

模板类二进制标志{

STATIC_ASSERT(0STATIC_ASSERT的第二个版本
您不能在同一块中逐个使用

template<int N, int M>
void foo ()
{
  STATIC_ASSERT(N<M), STATIC_ASSERT(M<0);  // error
};
模板
void foo()
{

STATIC_ASSERT(N我通常在自己的代码中使用第二个或它的一些变体。 实际上,增压变型具有可以使用的优点 表达式可能出现在任何地方,而不仅仅是在语句级别 它的缺点是,它只能在表达式可能出现的情况下使用
出现,因此不在命名空间范围内。

+1,但我仍然不明白第一个版本将如何发出代码?这些只是空的
struct
声明,仅对吗?@iammilind:有一个临时构造可能会发出一些代码。@sharptooth该类型是一个空的POD。我看不到任何构造会发出代码的场景不要忽略。也就是说,您选择第二种解决方案的另一点是有效的。选择其中一种或另一种的另一个原因可能是在失败时生成的错误有多好。我想在大多数平台上,typedef解决方案甚至在这方面都会更好。也不能保证typedef不会发出代码。例如,impLeMeNeX为其配置代码而编写其代码,允许在此处发射一些代码,以增加当前源文件行号的记录。这将符合标准。如果您只讨论VisualC++,那么对于每种断言,您可以检查它是否与编译器选项之间发出代码。尽管如此,我怀疑你会发现任何类型的优化都会出现问题。不过,有一些简单的方法可以解决这个问题(这些方法在“真正”的习语实现中使用)–例如,在typedef的名称后面加上
\uuuu LINE\uuuu
号:这很有趣-VC++9编译出来没问题。@老实说,我不认为在实践中有问题。一行一句话。这是一条如此简单的规则,没有理由违反它。@Sharptoth我相信VC++9是正确的。这应该只会失败w就我所知,typedef是不同类型的。在这种情况下,除非触发断言,否则永远不会发生这种情况。
#define STATIC_ASSERT( x ) typedef char __STATIC_ASSERT__[( x )?1:-1]
template<int Shift> class BinaryFlag {
    STATIC_ASSERT( 0 <= Shift && Shift < sizeof( DWORD) * CHAR_BIT );
    public:
    static const DWORD FlagValue = static_cast<DWORD>( 1 << Shift );
};
#define BINARY_FLAG( n ) CBinaryFlag<n>::FlagValue
template<int N, int M>
void foo ()
{
  STATIC_ASSERT(N<M), STATIC_ASSERT(M<0);  // error
};