Jon*_*han 1 c++ templates partial-specialization specialization template-specialization
如果我删除模板特化部分(试图打印"测试2"的部分),代码编译很好,但我希望能够有一个特殊情况,运行一个看起来干净的外部用户不同的代码路径.
#include <iostream>
using namespace std;
struct SpecialType {};
template<typename A , typename B = SpecialType>
class Test
{
public:
class TestInner
{
public:
TestInner& operator* ();
};
};
template<typename A , typename B>
typename Test<A , B>::TestInner& Test<A , B>::TestInner::operator* ()
{
cout << "Test 1" << endl;
return *this;
}
// If the following is removed, everything compiles/works, but I want this alternate code path:
template<typename A>
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator* ()
{
cout << "Test 2" << endl;
return *this;
}
int main()
{
Test<int , SpecialType>::TestInner test;
*test;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
编辑:顺便说一下,编译器错误读取:
main.cpp:26:44: error: 'Test<A, SpecialType>::TestInner' is not a type
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator* ()
^
main.cpp:26:89: error: invalid use of dependent type 'typename Test<A, SpecialType>::TestInner'
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator* ()
^
Run Code Online (Sandbox Code Playgroud)
为专门类添加声明:
template<typename A>
class Test<A, SpecialType>
{
public:
class TestInner
{
public:
TestInner& operator* ();
};
};
Run Code Online (Sandbox Code Playgroud)
问题是您为未声明的特化定义了一个成员.模板化类的特化不会与通用模板共享任何成员或方法,因此通用模板的声明不会作为该模板类的任何特化的声明.
考虑一下:
template <class T>
class Foo {
void GeneralFunction(T x);
}
Run Code Online (Sandbox Code Playgroud)
和专业化:
template <>
class Foo<int> {
void SpecialisedFunction(int x);
}
Run Code Online (Sandbox Code Playgroud)
这里,Foo</*anything except int*/>
只有方法,GeneralFunction
而Foo<int>
只有方法SpecialisedFunction
.
按照同样的逻辑,这也是允许的:
template<>
class Foo<float> {
float GeneralFunction; //here GeneralFunction is a data member, not a method.
}
Run Code Online (Sandbox Code Playgroud)
长话短说,你需要声明你的专业化.