私有类专门化错误

Private class specialization error

本文关键字:错误 专门化      更新时间:2023-10-16

在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("%sn", a.Name().c_str());
//  a.Print();
}

我已经尝试将Helper类的专门化移出BaseClass以与标准兼容:

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类为私有

你可以这样做:

#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("%sn", a.Name().c_str());
    //a.Print();
}

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

程序打印"Car"