C++ 从GCC 4.6更改为4.7时未定义的参考

C++ 从GCC 4.6更改为4.7时未定义的参考,c++,static,c++11,constants,C++,Static,C++11,Constants,我不得不从g++-4.6切换到4.7(这样我就可以使用一些C++11特性)。现在,编译器抱怨: 函数WordJIT::WordJIT()中的:对JitRegType::Val\u t的未定义引用 我想知道这些编译器版本之间是否发生了影响符号解析的变化。还是在新版本(4.7)中更好地实现了该语言,而我所做的是错误的:(4.6编译的代码相同) 准时制 类Jit{ 公众: 枚举RegType{f32=0,f64=1,u16=2,u32=3,u64=4,s16=5,s32=6,s64=7}; // ..

我不得不从g++-4.6切换到4.7(这样我就可以使用一些C++11特性)。现在,编译器抱怨:

函数WordJIT::WordJIT()中的
:对JitRegType::Val\u t的未定义引用

我想知道这些编译器版本之间是否发生了影响符号解析的变化。还是在新版本(4.7)中更好地实现了该语言,而我所做的是错误的:(4.6编译的代码相同)

准时制 类Jit{ 公众: 枚举RegType{f32=0,f64=1,u16=2,u32=3,u64=4,s16=5,s32=6,s64=7}; // ... }; 模板结构JitRegType{}; 模板结构JitRegType{static const Jit::RegType Val_t=Jit::f32;};
wordjit.h
#包括“jit.h”
模板
类WordJIT
{
WordJIT(){
insert(std::make_pair(JitRegType::Val_t,jit.getRegs(JitRegType::Val_t,1));
}
私人:
typedef std::mapMapRegType;
可变MapRegType mapReg;
};
编辑: 头文件中的
static const
正常吗,还是应该使用
constepr

是否有方法在
JitRegType
的类声明中声明
Val\t
,但不实际定义它?

根据9.4.2p3:

如果非易失性常量静态数据成员是整型或枚举类型,则其在类定义中的声明可以指定大括号或相等的初始值设定项[…]如果该成员在程序中使用odr,则仍应在命名空间范围中定义,且命名空间范围定义不应包含初始值设定项

因此,您需要添加到您的程序中(可能在
jit.cpp
中):

const Jit::RegType JitRegType::Val\t;
这是因为,如果在需要引用的上下文中使用
静态常量
成员,则链接器存在唯一的引用定义(与不是类模板或类模板部分专门化成员的任何
静态
成员相同)

对这个问题进行了深入讨论


请注意,gcc 4.6和4.7的行为都是合理的;只是GCC4.6选择内联
JitRegType::Val_t
的值,而GCC4.7选择不内联(或者可能是内联它,但也会发出对定义的链接器引用)。判断是否需要实现来发布诊断代码有点困难;9.4.2p3描述了一个可诊断规则,但9.4.2p4(暗指非
const
数据成员)表示不需要诊断。无论哪种方式,作为一个实现质量问题,编译器发出诊断比不发出诊断要好。

什么是
reg
in
reg(JitRegType::Val\t)?@PiotrNycz我将其替换为占位符,以避免过分夸大示例。但是,如上所述,您是否在切换到GCC4.7但仍停留在C++03时出现错误,或者您是否也启用了C++11?因为如果您选择了相同的C++标准版本,则应该在两个版本中实现名称解析,因为它们应该按照标准实现。<代码> -STD= C++ +0x在4.6和4.7中启用。我需要C++11在代码的其他部分的一般功能。现在我正在使用构造函数委托-切换到4.7肮脏解决方案的原因是:使
reg(…)
接受int而不是
RegType
,或者强制转换它。但是如果有人知道这在4.6中起作用而在4.7中不起作用的原因,那就更好了…@Frank gcc 4.6正在内联该值(它可以从标题访问该值),并且不发送对该值的链接器引用。严格地说,如果没有定义,您的程序是不正确的,即使GCC4.6编译了它。哇!这一点很重要。当切换到4.7时,可能会中断大量代码,显然4.7更严格地实现了该语言。非常感谢!!
class Jit {
  public:
    enum RegType { f32=0,f64=1,u16=2,u32=3,u64=4,s16=5,s32=6,s64=7 };
  // ...
};

template <class T> struct JitRegType {};
template <> struct JitRegType<float>  { static const Jit::RegType Val_t = Jit::f32; };
  #include "jit.h"

  template<class T>
  class WordJIT 
  {
    WordJIT() {
      mapReg.insert( std::make_pair( JitRegType<T>::Val_t , jit.getRegs( JitRegType<T>::Val_t , 1 ) ) );
    }
    private:
      typedef std::map< Jit::RegType , int > MapRegType;
      mutable MapRegType mapReg;
  };
const Jit::RegType JitRegType<float>::Val_t;