类模板专门化的问题 [英] Problem with class template specialisations

查看:153
本文介绍了类模板专门化的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将一些代码从VC9移植到G ++,但是我遇到了模板专门化的问题,显然不允许类成员使用。



以下代码是类方法的getValue特化的这些错误的示例。在任何情况下,错误都是错误:在非名称空间范围 class ... 中显式专用化

 模板< typename T> T getValue(const_iterator key)const 
{
try {return boost :: lexical_cast< T>(key-> second);}
catch(boost :: bad_lexical_cast& e)
{
throw TypeParseError< T>(name,key-> first,e.what());
}
}
模板< typename T> T getValue(const std :: string& key)const
{
iterator i = find(key);
if(i == end())throw KeyNotFound(name,key);
else return getValue(i);
}
模板<> std :: string getValue< std :: string>(const_iterator key)const
{
return key-> second;
}
模板<> std :: string getValue< std :: string>(const std :: string& key)const
{
const_iterator i = find(key);
if(i == end())throw KeyNotFound(name,key);
else返回i->秒;
}

它只是不支持确切的语法,让它工作,还是我需要更改代码以避免这样的专业化?如果后者是一般这样做的最好方法?

解决方案

您没有显示包含这些函数的类定义-declarations。但我认为这是一些声明这些模板的类。你必须在外面定义专门化:

  struct SomeClass {
模板< typename T> T getValue(const_iterator key)const
{
try {return boost :: lexical_cast< T>(key-> second);}
catch(boost :: bad_lexical_cast& e)
{
throw TypeParseError< T>(name,key-> first,e.what());
}
}
模板< typename T> T getValue(const std :: string& key)const
{
iterator i = find(key);
if(i == end())throw KeyNotFound(name,key);
else return getValue(i);
}
};

模板<> inline std :: string SomeClass :: getValue< std :: string>(const_iterator key)const {
return key-> second;
}

模板<> inline std :: string SomeClass :: getValue< std :: string>(const std :: string& key)const {
const_iterator i = find(key);
if(i == end())throw KeyNotFound(name,key);
else返回i->秒;

$ / code>

请记住,由于您在外界定义了它们,因此它们不是内联的,所以你必须显式地将它们内联,或者将它们移动到 cpp 文件(不是头文件)中,然后在头文件中正向声明特化项,如下所示:

 模板<> inline std :: string SomeClass :: getValue< std :: string>(const_iterator key)const; 
模板<> inline std :: string SomeClass :: getValue< std :: string>(const std :: string& key)const;

如果您省略前向声明,编译器无法知道是否实例化函数或使用明确的专业化。前向声明告诉它。

I'm trying to port some code from VC9 to G++, however Ive run into a problem with template specialisations apparently not being allowed for class members.

The following code is an example of these errors for the getValue specialisations of the class methods. In all cases the error is "error: explicit specialization in non-namespace scope class ..."

template<typename T> T getValue(const_iterator key)const
{
    try{return boost::lexical_cast<T>(key->second);}
    catch(boost::bad_lexical_cast &e)
    {
        throw TypeParseError<T>(name, key->first, e.what());
    }
}
template<typename T> T getValue(const std::string &key)const
{
    iterator i = find(key);
    if(i == end())throw KeyNotFound(name,key);
    else return getValue(i);
}
template<> std::string getValue<std::string>(const_iterator key)const
{
    return key->second;
}
template<> std::string getValue<std::string>(const std::string &key)const
{
    const_iterator i = find(key);
    if(i == end())throw KeyNotFound(name,key);
    else return i->second;
}

Is it just the exact syntax is not supported, and that a minor change will make it work, or will I need to change the code to avoid specialisations like this? If the latter which is the best way to do so in general?

解决方案

You haven't shown the class definition enclosing these function-declarations. But i assume it's some class where these templates are declared in. You have to define the specializations outside:

struct SomeClass {
   template<typename T> T getValue(const_iterator key)const
    {
        try{return boost::lexical_cast<T>(key->second);}
        catch(boost::bad_lexical_cast &e)
        {
            throw TypeParseError<T>(name, key->first, e.what());
        }
    }
    template<typename T> T getValue(const std::string &key)const
    {
        iterator i = find(key);
        if(i == end())throw KeyNotFound(name,key);
        else return getValue(i);
    }
};

template<> inline std::string SomeClass::getValue<std::string>(const_iterator key)const {
    return key->second;
}

template<> inline std::string SomeClass::getValue<std::string>(const std::string &key)const {
    const_iterator i = find(key);
    if(i == end())throw KeyNotFound(name,key);
    else return i->second;
}

Remember that since you have defined them outside, they are not inline implicitly, so you either have to make them inline explicitly, or move them into a cpp file (not a header), and forward-declare the specializations in the header like this:

template<> inline std::string SomeClass::getValue<std::string>(const_iterator key)const;
template<> inline std::string SomeClass::getValue<std::string>(const std::string &key)const;

If you omit the forward-declaration, the compiler has no way to know whether to instantiate the functions or to use the explicit specializations. The forward declaration tells it.

这篇关于类模板专门化的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆