【发布时间】:2014-10-08 07:25:19
【问题描述】:
我正在使用 C++ 开发一个跨平台库。 MSVC 编译得很好,但 g++ 给我带来了问题。假设我有以下 Enum 助手类:
// File: Enum.h
#ifndef ENUM_H
#define ENUM_H
#include <map>
#include <cstring>
namespace MyLib {
#define DECLARE_ENUM( type ) template<> std::map<const char*, type> \
MyLib::Enum<type>::mMap = std::map<const char*, type>(); \
template<> MyLib::Enum<type>::Enum (void)
template <typename Type> class Enum
{
private:
Enum (void);
public:
static int Size (void) { /* ... */ return 0; }
private:
static std::map<const char*, Type> mMap;
};
}
#endif
这是预期用途:
// SomeFile.cpp
#include "Enum.h"
enum MyEnum
{
value1, value2, value3,
};
DECLARE_ENUM (MyEnum)
{
mMap["value1"] = value1;
mMap["value2"] = value2;
mMap["value3"] = value3;
}
void SomeFunc (void)
{
cout << Enum<MyEnum>::Size();
}
g++ 给了我一个“不同命名空间中模板的专业化”错误。在命名空间 MyLib 中包装 DECLARE_ENUM 块可以解决这个问题。我的问题是为什么我必须这样做,有没有另一种方法可以解决这个问题,不需要我在块周围添加命名空间 MyLib?
【问题讨论】:
-
不要使用宏,尤其是头文件中。
-
@RobertAllanHenniganLeahy 这里不同。请注意,这个宏指定了
MyLib::,并且它明确地专门化了一个隐式实例化的成员。其实clangaccepts这段代码取模错别字。 -
Here's yet another similar question 读者可能会感兴趣。
标签: c++ templates ubuntu c++11 g++