模板在不同命名空间中的专业化 [英] Specialization of template in different namespace
问题描述
我正在开发一个使用C ++的跨平台库。 MSVC编译好,但g ++给我的问题。假设我有以下Enum helper类:
//文件:Enum.h
#ifndef ENUM_H
#define ENUM_H
#include< map>
#include< cstring>
命名空间MyLib {
#define DECLARE_ENUM(type)template<> std :: map< const char *,type> \
MyLib :: Enum< type> :: mMap = std :: map< const char *,type>(); \
模板<> MyLib :: Enum< type> :: Enum(void)
模板< typename类型> class Enum
{
private:
Enum(void);
public:
static int Size(void){/ * ... * / return 0; }
private:
static std :: map< const char *,Type> MMAP;
};
}
#endif
以下是预期用途:
// SomeFile.cpp
#includeEnum.h
enEn MyEnum
{
value1,value2,value3,
};
DECLARE_ENUM(MyEnum)
{
mMap [value1] = value1;
mMap [value2] = value2;
mMap [value3] = value3;
}
void SomeFunc(void)
{
cout<<枚举< MyEnum> ::尺寸();
}
g ++给了我一个不同命名空间中的模板专业化错误。在命名空间MyLib中包装DECLARE_ENUM块可解决此问题。我的问题是为什么我必须这样做,是否有另一种解决这个问题的方法,不需要我在块的周围添加一个名称空间MyLib?
由于 CWG issue 374 and N3064 。当前的措词(§14.7.3[temp.expl.spec] / p2)是:
lockquote
明确的特殊化应在命名空间包含
专用模板。一个明确的特殊化,其
declarator-id 不合格应在模板的最近
封闭名称空间中声明,或者如果名称空间是内联
(7.3 。
由于您的 declarator-id 实际上是事实上的使用 MyLib ::
进行限定,全局名称空间是一个封装专用模板的名称空间,这看起来像是一个GCC错误( bug 56480 )。您的代码可以通过 C ++ 11模式中的clang 进行编译。
然而,在C ++ 98中,专业化必须放在模板是其成员的命名空间内(见下面的Mark B的注释),并且如果放入C ++ 98模式。
I'm developing a cross-platform library using C++. MSVC compiles fine but g++ is giving me problems. Suppose I have the following Enum helper class:
// 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
Here is the intended use:
// 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++ gives me a "Specialization of template in different namespace" error. Wrapping the DECLARE_ENUM block in namespace MyLib solves this problem. My question is why do I have to do this and is there another way of fixing this that doesn't require me to add a namespace MyLib around the block?
This changed in C++11 as a result of CWG issue 374 and N3064. The current wording (§14.7.3 [temp.expl.spec]/p2) is:
An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit specialization whose declarator-id is not qualified shall be declared in the nearest enclosing namespace of the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set.
Since your declarator-id is in fact qualified with MyLib::
, and the global namespace is a "namespace enclosing the specialized template", this looks like a GCC bug (bug 56480). Your code compiles fine with clang in C++11 mode.
In C++98, however, the specialization must be put inside namespace in which the template is a member (see Mark B's comment below), and clang will produce a warning if put in C++98 mode.
这篇关于模板在不同命名空间中的专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!