简体   繁体   English

C ++模板专业化:编译错误:“不是类型”

[英]C++ Template Specialization: compile error: “is not a type”

If I remove the template specialization part (the one that tries to print "Test 2"), the code compiles fine, but I'd like to be able to have a special case that runs a different code path that looks clean to outside users. 如果我删除模板专门化部分(尝试打印“ Test 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;
}

What am I doing wrong? 我究竟做错了什么?

Edit: By the way, the compiler error reads: 编辑:顺便说一下,编译器错误显示为:

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* ()
                                                                                         ^

Add a declaration for the specialised class: 为特殊类添加一个声明:

template<typename A>
class Test<A, SpecialType>
{
public:
    class TestInner
    {
    public:
        TestInner& operator* ();
    };
};

The problem is that you define an member for a specialization that is not declared. 问题是您为未声明的专业定义了成员。 A specialization of a templated class does not share any members or methods with the generalised template, so the declaration of the generalised template doesn't serve as a declaration of any specialisations of that template class. 模板化类的特殊化不与通用化模板共享任何成员或方法,因此,通用化模板的声明不充当该模板类的任何特殊化的声明。

Consider this: 考虑一下:

template <class T>
class Foo {
  void GeneralFunction(T x);
}

and a specialization: 和专业化:

template <>
class Foo<int> {
  void SpecialisedFunction(int x);
}

Here, Foo</*anything except int*/> has only the method GeneralFunction whereas Foo<int> has only the method SpecialisedFunction . 在这里, Foo</*anything except int*/>只有方法GeneralFunctionFoo<int>只有方法SpecialisedFunction

By the same logic, this is allowed also: 按照相同的逻辑,这也是允许的:

template<>
class Foo<float> {
  float GeneralFunction; //here GeneralFunction is a data member, not a method.
}

Long story short you need to declare you specialisation. 长话短说,您需要声明自己的专业。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM