【问题标题】:Using a Class Template's Internal Types from a Specialized Class从专门的类中使用类模板的内部类型
【发布时间】:2015-12-22 15:26:37
【问题描述】:

编辑:当我去度假时,我实际上并没有机会测试任何建议的解决方案,当我回来时,负责课程模板的人进行了一些更改,使我能够绕过使用类模板本身中定义的类型的需要。

感谢大家的帮助。


简而言之 - 随意更正我的措辞,模板对我来说仍然有点巫术, - 我需要知道我是否可以使用 (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 );
};

我需要完全专注于T = VAL

template<>
class A< VAL > : public C< VAL >
{
    void foo( a_struct a )
    {
        // My implementation of foo, different from the class template's
    }
};

但是,如果我这样做,编译器会抱怨 a_struct 在我的专用类中未定义。我尝试专门化并从类模板继承,但这变得……混乱。

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

想法?

【问题讨论】:

  • 查看关于 SO 的许多其他问题之一,其中解释了模板中对 typename 的需求:stackoverflow.com/questions/610245/…
  • 对不起,我最初误解了你的问题。您不想从基类继承类型,而是从自己的非专业版本继承。
  • 我认为你可以在不“修改”原件的情况下创建一个假基地。创建一个继承自原始的类并与假基类成为朋友,因此假基类可以将类型定义从原始保护区域窃取到自己的保护区域中。然后使用那个假基地作为专业化的真实基地。

标签: c++ templates template-specialization specialization


【解决方案1】:

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

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

  • 您可以专门化模板类成员函数。如果确实只有一个特殊的成员函数(或至少成员函数的数量有限),这很有用。
  • 您可以将成员 (-type) 的声明带入公共基类中。

由于您在编辑中指出不能更改类模板本身,因此专门化成员函数似乎是最佳选择。

一个简化的example 只专门化一个成员函数

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";
}

此处的Guard 仅用于证明此类型可用于DoPrint() 的主要实现和专用实现。

【讨论】:

    【解决方案2】:

    它并不漂亮,但你可以这样做:

    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
        }
    };
    

    【讨论】:

      【解决方案3】:

      或者如何,在专用模板中重新声明 struct a_struct,其功能与默认模板相同。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-13
        相关资源
        最近更新 更多