如何在不修改主模板的情况下从专用化调用主类模板的成员函数

How to call a member function of the primary class template from a specialization, without modifying the primary template

提问人:Akshay Kalghatgi 提问时间:10/13/2023 最后编辑:Akshay Kalghatgi 更新时间:10/14/2023 访问量:105

问:

我正在寻找一种从类模板专用化中的成员函数调用主类模板成员函数的方法。 这类似于我们从覆盖的派生类成员函数调用基类虚拟成员函数的方式。

// Template defintion
template <typename T>
class MyClass final
{
    ...
    void foo() { ... };
}
// Template specialization for method foo
template<>
void MyClass<MyType>::foo()
{
   ...
   // call primary template's foo() here??
   // MyClass::free(); // Warning: All paths through this function will call itself
}

注意:我不拥有包含主模板定义的代码,只拥有模板专用化部分。我正在寻找这些限制内的解决方案。有一个类似的问题:如何在没有这些限制的情况下从专用化的成员函数调用主类模板的成员函数,我不能在那里使用答案。

C++ 模板专用 化类模板

评论

1赞 Weijun Zhou 10/13/2023
术语说明:模板专用化不是继承,因此在题目标题中可能不合适。你的意思是.baseprimary template
2赞 Igor Tandetnik 10/13/2023
没办法。专业化完全取代了主模板;主模板永远不会使用专用化所涵盖的参数集进行实例化。您可以定义一个辅助方法(例如,),主方法和专用化方法都委托给该方法,并在那里实现“主线”工作。foo_impl
3赞 konchy 10/13/2023
链接这回答了你的问题吗?
0赞 Akshay Kalghatgi 10/13/2023
谢谢@konchy。这个问题和我的问题一样,只是我不能改变主模板类,所以该解决方案将不起作用。
0赞 Akshay Kalghatgi 10/13/2023
谢谢@IgorTandetnik。我相信你是对的,如果不修改主模板类实现,就没有办法解决这个问题

答:

0赞 Klaus 10/13/2023 #1

只需使用以前没有专用的新类型来调用主 none 专用模板。

像这样:

 template < typename T>
struct MyClass 
{
    void Foo() { std::cout << "PrimaryFoo" << std::endl; }
};

template <>
void MyClass<double>::Foo() 
{
    std::cout << "Spezialized for double" << std::endl; 
    // and now call the primary template
    // simply define a type where MyClass is not specialized for
    struct Dummy;
    MyClass<Dummy>{}.Foo();
}

int main()
{
    MyClass<double>{}.Foo();
}

很明显,如果你需要你的主类具有与你的专业化相同的数据类型,这将无济于事,因为它访问其中的一些数据。

0赞 Jan Schultke 10/13/2023 #2

没有干净的方法可以完成您的任务。当你问

我如何拨打电话?MyClass<X>::fooMyClass<Y>::foo

...这就像问

我如何拨打电话?std::string::size()std::vector<char>::size()

这根本不可能;您正在使用不同的类型。唯一的共同点是名字。MyClass<X>MyClass<Y>

如果允许修改主模板,则可以使所有内容都继承自类(模板),并且该类可以包含成员非专用成员函数。您可以创建一个新实例并调用其 ,但这只会访问此新对象的数据成员。MyClassMyClassBaseMyClass<X>MyClass<X>::foo

一种可能的解决方案是从使用主模板的东西继承:

template <typename T>
struct MyClass {
    /* ... */
    void foo() { /* ... */ }
};

template <>
struct MyClass<MyType> : private MyClass<void> {
    void foo() { // this is not overriding; it is shadowing
        // ...
        MyClass<void>::foo(); // call primary template member function
    }
};

这确实解决了问题,但这也意味着您继承了(或其他)基类的所有数据成员。MyClass<void>

评论

1赞 Raymond Chen 10/14/2023
你可以通过简单地决定这是基础来完成。 现在到处使用。MyClassBaseMyClasstemplate<typename T> struct MyBetterClass : MyClass<T> {}; template<> struct MyBetterClass<MyType> : MyClass<MyType> { void foo() { extra_stuff(); MyClass::foo(); } };MyBetterClass<T>