2011-05-01 33 views
1

这是my previous question的延续。专门编译器错误C3855(MSVC9)中的嵌套类静态函数结果

我想创建一个嵌套类模板的类模板,其中嵌套类模板有一个静态函数,我想提供一个专业化。

这里是我的测试代码,它没有提供嵌套类的专业化。请注意空类NullType的存在 - 这是我想要专门化嵌套类。

#include <cstdlib> 
#include <iostream> 
using namespace std; 

class NullType {}; 

template<class FooParam> struct Foo 
{ 
    template<class BarParam> struct Bar 
    { 
     static bool Magic(); 
    }; 
}; 

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Bar<BarParam>::Magic() 
{ 
    return true; 
} 

int main() 
{ 
    bool b = Foo<int>::Bar<int>::Magic(); 
    cout << b << " "; 
    bool b2 = Foo<int>::Bar<NullType>::Magic(); 
    cout << b2 << " "; 

} 

此代码编译并按预期运行。输出是:

1 1 

现在我想提供NullTypeBar::Magic一个专业化,有函数返回false。所需的输出是:

1 0 

所以我试图写的专业化是这样的:

template<class FooParam> 
template<> 
bool Foo<FooParam>::Bar<NullType>::Magic() 
{ 
    return false; 
} // COMPILER ERROR HERE C3855 

这个定义Foo::Bar::Magic()现有定义之前出现。

然而,该代码产生一个编译错误:

1>.\main.cpp(20) : error C3855: 'Foo<FooParam>::Bar<BarParam>': template parameter 'BarParam' is incompatible with the declaration 

...的闭括号上面所指出的。

我可以用什么语法来提供这种专业化?我愿意接受任何和所有的技术来实现我的主要目标(其他一切返回falseNullTypetrue),只要:

  1. 无需外部库使用(增强)
  2. 它采用兼容标准的C++只有
  3. Foo是一个类模板,Bar是嵌套类模板或函数模板。返回falsetrue的函数必须是特殊化的或可重载的,以便调用NullType的代码返回false,但其他所有操作都将返回true

我会在需要时澄清要求。

+0

根据14.7.3/18, 构件模板不能被其包围类模板之前专门 是专门。 所以,你的要求可能无法得到满足,因为它是... – 2011-05-01 19:59:40

回答

1

一个快速解决方案是使用标准C++(5.2.8)的typeid运算符。所以,你的魔法()函数的内容如下:

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Bar<BarParam>::Magic() 
{ 
    if (typeid(BarParam) == typeid(NullType)) 
     return false; 

    return true; 
} 

据我所知,编译器都在实际执行的typeid和所属类别的一些自由,但是==操作符是保证工作像你期望它来。需要注意的是,显然有些编译器为了性能而默认不支持运行时类型信息;大多数应该有一个标志来打开它。

2

没有其封闭类的专业化的嵌套类/方法的专业化被两个C++ 03和C++ 11禁止,如在@Ise紫藤的评论中提及。

但愿采用超负荷工作,为您以下解决方案?

#include <cstdlib> 
#include <iostream> 
using namespace std; 

class NullType {}; 

template<class FooParam> struct Foo 
{ 
    template<class BarParam> static bool Magic(BarParam); 
    static bool Magic(NullType); 
}; 

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Magic(BarParam) 
{ 
    return true; 
} 

template<class FooParam> 
bool Foo<FooParam>::Magic(NullType) 
{ 
    return false; 
} 

int main() 
{ 
    bool b = Foo<int>::Magic(int()); 
    cout << b << " "; 
    bool b2 = Foo<int>::Magic(NullType()); 
    cout << b2 << " "; 
} 
2

另一可选变型是使用非嵌套性状类:

class NullType {}; 

template<class FooParam> struct Foo 
{ 
    template<class BarParam> struct Bar 
    { 
     static bool Magic(); 
    }; 
}; 

template<class T> struct bool_trait 
{ 
    static const bool value = true; 
}; 

template<> struct bool_trait<NullType> 
{ 
    static const bool value = false; 
}; 

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Bar<BarParam>::Magic() 
{ 
    return bool_trait<BarParam>::value; 
}