私有类专业化错误

时间:2015-06-07 22:52:16

标签: c++ c++11 clang

在编译期间,clang中的代码有警告(在vc ++中它可以正常工作):

  

警告:类范围内'Helper'的显式特化是一个   Microsoft扩展[-Wmicrosoft]

#include <stdio.h>
#include <string>

enum class Car { BMW };

class C
{
    static void Method() { puts("inner");}
};

template<typename T>
class BaseClass
{
private:
    template<typename V> 
    struct Helper;

    template<>
    struct Helper<Car>
    {
        typedef C InnerType;
        static const char* Name() { return "Car"; }
    };

    typedef Helper<T> Info;
    typedef typename Info::InnerType InnerType;

private:
    T v;

protected:
    BaseClass()
    { }

public:
    T Value() const { return v; }
    std::string Name() const { return Info::Name(); }
    static void Print() { InnerType::Method(); }
};


class MyCar : public BaseClass<Car>
{
public:
    MyCar() : BaseClass() {}
};

int main()
{
    MyCar a;
    printf("%s\n", a.Name().c_str());
//  a.Print();
}

我试图将BaseClass之外的Helper类专门化与标准兼容:

template<> template<>
struct BaseClass<Car>::Helper<Car>
{
    typedef C InnerType;
    static const char* Name() { return "Car"; }
};

但现在我有编译错误:

  

错误:隐式实例化未定义模板'BaseClass :: Helper'

如果我删除该行:typedef typename Info::InnerType InnerType;(以及函数Print中的相关用法),那么一切正常。

是否可以修复此错误?我想将我的Helper课程保密。

1 个答案:

答案 0 :(得分:2)

你可以这样做:

#include <stdio.h>
#include <string>

enum class Car { BMW };

class C
{
    static void Method() { puts("inner");}
};

template<typename T>
class BaseClass
{
private:
    template<typename V> 
    struct Helper;

    template<typename V>
    using Info = Helper<V>;

    template<typename V>
    using InnerType = typename Info<V>::InnerType;


private:
    T v;

protected:
    BaseClass()
    { }

public:
    T Value() const { return v; }
    std::string Name() const { return Info<T>::Name(); }
    static void Print() { InnerType<T>::Method(); }
};

template<> template<>
struct BaseClass<Car>::Helper<Car>
{
    typedef C InnerType;
    static const char* Name() { return "Car"; }
};


class MyCar : public BaseClass<Car>
{
public:
    MyCar() : BaseClass() {}
};

int main()
{
    MyCar a;
    printf("%s\n", a.Name().c_str());
    //a.Print();
}

(gcc 5.1 / clang 3.6,-std = C ++ 11)

程序打印&#34; Car&#34;。