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
C++ 为什么我会得到;冲突声明“;在gcc和模板函数中使用两个或更多基于typedef的静态断言时出错?_C++_Templates_Gcc_Static Assert - Fatal编程技术网

C++ 为什么我会得到;冲突声明“;在gcc和模板函数中使用两个或更多基于typedef的静态断言时出错?

C++ 为什么我会得到;冲突声明“;在gcc和模板函数中使用两个或更多基于typedef的静态断言时出错?,c++,templates,gcc,static-assert,C++,Templates,Gcc,Static Assert,我有以下代码(不,模板没有在任何地方实例化): 如果我只留下一个cAssert()(两个中的任何一个)-它编译得很好。问题是,只有当我同时拥有它们的时候 为什么gcc会拒绝此代码,我如何修复此代码?我不知道为什么这不起作用 一个半修复: #define cAssertbraces( expr ) typedef char __C_ASSERT_BRACES__[( expr )?1:-1] template<class T> void cAssert(T v1, T v2) {

我有以下代码(不,模板没有在任何地方实例化):

如果我只留下一个
cAssert()
(两个中的任何一个)-它编译得很好。问题是,只有当我同时拥有它们的时候


为什么gcc会拒绝此代码,我如何修复此代码?

我不知道为什么这不起作用

一个半修复:

#define cAssertbraces( expr ) typedef char __C_ASSERT_BRACES__[( expr )?1:-1]

template<class T>
void cAssert(T v1, T v2) {  {cAssertbraces( v1 != v2 );} }

template<int t>
void f()
{  
    {cAssertbraces( t != 0 );}
    {cAssertbraces( t != 2 );}
    cAssert(t, 0);
    cAssert(t, 2);
}

这是我从这里得到的(很好的答案,应该检查)。

GCC拒绝代码的原因本质上是,在宏被扩展后,您有一个不同的令牌序列,包含类型声明。考虑一个更容易的例子:

template <unsigned t>
void f()
{  
    using type = int[t + 0];
    using type = int[t    ]; // Adding a +0 here makes GCC compile it fine
}
模板
void f()
{  
使用type=int[t+0];
使用type=int[t];//在这里添加+0可以使GCC编译它
}
。然而,这一点已包含在合同中,CWG的结论是:

我们认为所有这些情况都是允许的,并且只有在生成模板实例时才需要错误。目前的标准措辞似乎并不禁止此类情况,因此无需进行更改。


也就是说,GCC是错误的。

不是答案,但为什么不使用而不是滚动自己的?不知道GCC是否正确,但您应该能够通过在每个
cAssert
表达式周围添加大括号来修复错误。netbeans中的cygwin将产生相同的错误。@Praetorian您到底打算怎么做?我试过了,但失败了。错误报告@萨马拉斯
{cAssert(t!=0);}
#define cAssertbraces( expr ) typedef char __C_ASSERT_BRACES__[( expr )?1:-1]

template<class T>
void cAssert(T v1, T v2) {  {cAssertbraces( v1 != v2 );} }

template<int t>
void f()
{  
    {cAssertbraces( t != 0 );}
    {cAssertbraces( t != 2 );}
    cAssert(t, 0);
    cAssert(t, 2);
}
#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1]
#define COMPILE_TIME_ASSERT3(X,L) STATIC_ASSERT(X,static_assertion_at_line_##L)
#define COMPILE_TIME_ASSERT2(X,L) COMPILE_TIME_ASSERT3(X,L)
#define COMPILE_TIME_ASSERT(X)    COMPILE_TIME_ASSERT2(X,__LINE__)

...
COMPILE_TIME_ASSERT( t != 2 );
template <unsigned t>
void f()
{  
    using type = int[t + 0];
    using type = int[t    ]; // Adding a +0 here makes GCC compile it fine
}