C++ 使用类模板';从专用类中删除内部类型

C++ 使用类模板';从专用类中删除内部类型,c++,templates,template-specialization,specialization,C++,Templates,Template Specialization,Specialization,编辑:在度假期间,我实际上没有机会测试任何建议的解决方案,而在我回来的时候,负责类模板的人员已经做了一些更改,允许我绕过使用类模板中定义的类型的需要 谢谢大家的帮助 简言之——请随意更正我的措辞,模板对我来说仍然有点巫毒——我需要知道我是否可以使用(protected)struct或在我的专业类的类模板中定义的#typedef。例如: 这是类模板: template<typename T> class A : public C<T> { protected: s

编辑:在度假期间,我实际上没有机会测试任何建议的解决方案,而在我回来的时候,负责类模板的人员已经做了一些更改,允许我绕过使用类模板中定义的类型的需要

谢谢大家的帮助


简言之——请随意更正我的措辞,模板对我来说仍然有点巫毒——我需要知道我是否可以使用(
protected
struct
或在我的专业类的类模板中定义的
#typedef
。例如:

这是类模板:

template<typename T>
class A : public C<T>
{
protected:
    struct a_struct { /* Class template implementation, doesn't depend on T */ };
    void foo( a_struct a );
};
但是,如果我这样做,编译器会抱怨
a_struct
在我的专用类中未定义。我尝试从类模板中进行专门化和继承,但结果。。。乱七八糟的

我看到了一些解决方案,但都涉及到修改类模板,这是我不容易做到的(不同的团队)


想法?

它并不美丽,但你可以这样做:

template<typename T>
class C
{

};

template<typename T>
class A : public C<T>
{
protected:
    friend A<int>;
  // ^^^^^^
    struct a_struct { /* Class template implementation, doesn't depend on T */ };
    void foo( a_struct a );
};

template<>
class A< int > : public C< int >
{
    using a_struct = typename A<void>::a_struct;
  // ^^^^^^
    void foo( a_struct a )
    {
        // My implementation of foo, different from the class template's
    }
};
模板
C类
{
};
模板
A类:公共C类
{
受保护的:
朋友A;
// ^^^^^^
struct a_struct{/*类模板实现,不依赖于t*/};
void foo(结构a);
};
模板
A类:公共C
{
使用a_struct=typename a::a_struct;
// ^^^^^^
void foo(结构a)
{
//我的foo实现不同于类模板的
}
};

否,在类模板的专门化中不能使用主模板声明的成员。这是因为在本质上,模板类专门化声明了一个全新的类模板,当模板参数与专门化匹配时应用该模板

但是,如果要执行示例中的操作,您有两个可用选项:

  • 您可以专门化模板类成员函数。如果确实只有一个成员函数是特殊的(或者至少成员函数的数量是有限的),那么这非常有用
  • 您可以将成员(-type)的声明带到公共基类中
因为您在编辑中指出不能更改类模板本身,所以专门化成员函数似乎是最好的选择

仅对成员函数进行专门化的简化方法

template< class T>
class Printer
{
public:
    struct Guard {};
    void DoPrint( const T& val)
    {
        Guard g;
        (void)g;
        std::cout << val << '\n';
    }
};

struct Duck {};

template<>
void Printer<Duck>::DoPrint( const Duck& val)
{
    Guard g;
    (void)g;
    std::cout << "Some duck\n";
}
模板
类打印机
{
公众:
结构保护{};
无效数据打印(常数T&val)
{
防护罩g;
(b)g;

std::cout或者,在专用模板中重新声明struct a_struct,使用与默认模板相同的功能


我知道这听起来可能不太好,因为你需要注入所有专门的模板。但这是我现在可以想到的一个问题。

看看其他许多问题中的一个,其中解释了在模板中需要
typename
:对不起,我最初误解了你的问题。你不想从基类继承类型,但是她来自于你的非专业化版本。我认为你可以在不“修改”的情况下创建一个假基地原始。创建一个从原始库继承的类并与假库建立友谊,这样假库就可以将类型定义从原始库的保护区域窃取到它自己的保护区域中。然后使用该假库作为专门化的真实库。
template< class T>
class Printer
{
public:
    struct Guard {};
    void DoPrint( const T& val)
    {
        Guard g;
        (void)g;
        std::cout << val << '\n';
    }
};

struct Duck {};

template<>
void Printer<Duck>::DoPrint( const Duck& val)
{
    Guard g;
    (void)g;
    std::cout << "Some duck\n";
}