【问题标题】:Specialise only parts of template class while keeping the rest generic仅专门化模板类的一部分,同时保持其余部分通用
【发布时间】:2020-04-15 02:50:17
【问题描述】:

假设以下类:

template <typename T>
class Test {
public:
    void do_something1();
    ...
    void do_something100(); // basically many functions already defined
}

如何在不重写所有可能已经模板化的 100 个函数的情况下向类的特化添加另一个函数?

template<>
class Test<int> {
public:
    void do_something_else();
}

...

int main() {
    auto x = Test<int>();
    x.do_something5();     // should be still valid, would call 
                           // Test<T>::do_something5() with T being int
    x.do_something_else(); // valid because declared in specialisation
    ...
}

现在,如果像上面的示例一样保留Test&lt;int&gt; 特化,它将只包含do_something_else(),不包含do_something1...100()


解决方案

根据接受的答案,使用给定的示例,我执行了以下操作:

namespace parent {
    template <typename T>
    class Test {
    public:
        void do_something1();
        ...
        void do_something100(); 
    }
}

template <typename T>
class Test : public parent::Test<T> {
    using parent::Test<T>::Test; // inherit constructors
}

template <>
class Test<int> : public parent::Test<int> {
    using parent::Test<int>::Test;
public:
    void do_something_else();
}

【问题讨论】:

  • 不幸的是,C++ 不能以这种方式工作。您将不得不找到一些方法来重新设计您的模板。可能把常用的函数放在父模板类中,在子类中继承,默认实现,还有一些特化。

标签: c++ class templates


【解决方案1】:

您可以创建一个通用基类,并从它派生主模板和特化。

或者您可以制作do_something_else 函数模板并且仅适用于int(然后不需要使用专门化)。

template <typename T>
class Test {
public:
    void do_something1();
    ...
    void do_something100(); // basically many functions already defined

    template <typename X = T>
    std::enable_if_t<std::is_same_v<X, int> && std::is_same_v<X, T>> do_something_else();
};

或者从 C++20 开始,我们可以按照@aschepler 的建议使用约束

template <typename T>
class Test {
public:
    void do_something1();
    ...
    void do_something100(); // basically many functions already defined

    void do_something_else() requires std::is_same_v<T, int>;
};

【讨论】:

  • 我尝试了通用的基类方法,它可以工作。与 std::enab... 混乱相比,它肯定是更好的解决方案。只有添加一两个额外的方法,std::enab... 的混乱可能才值得。
  • 或者在 C++20 中,只需 void do_something_else() requires std::is_same_v&lt;T, int&gt;;...
  • @aschepler 是的,它很优雅。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
相关资源
最近更新 更多