【问题标题】:C++ Template Specialization: compile error: "is not a type"C++ 模板专业化:编译错误:“不是类型”
【发布时间】:2014-02-11 12:12:32
【问题描述】:

如果我删除模板专业化部分(尝试打印“测试 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;
}

我做错了什么?

编辑: 顺便说一句,编译器错误显示:

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

【问题讨论】:

    标签: c++ templates template-specialization specialization partial-specialization


    【解决方案1】:

    为特殊类添加声明:

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

    问题在于您为未声明的特化定义了一个成员。模板类的特化不与泛化模板共享任何成员或方法,因此泛化模板的声明不用作该模板类的任何特化的声明。

    考虑一下:

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

    和专业化:

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

    这里,Foo&lt;/*anything except int*/&gt; 仅具有方法 GeneralFunction,而 Foo&lt;int&gt; 仅具有方法 SpecialisedFunction

    按照同样的逻辑,这也是允许的:

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

    长话短说,你需要声明你的专业。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 2018-06-22
    • 2020-07-18
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多