【问题标题】:Is there a way to call a template constructor from a specialized constructor?有没有办法从专门的构造函数调用模板构造函数?
【发布时间】:2021-11-11 10:44:37
【问题描述】:

假设我有这门课:

template <class T>
class Test
{
    Test(T* x);

    const T* const t;
    int i{0};
};

我希望 t 始终使用 x 进行初始化:

template <class T> Test<T>::Test(T* x) : t{x} {}

我有两个专业:

template <> Test<Foo>::Test(Foo* x) : t{x} { i = 1; }
template <> Test<Bar>::Test(Bar* x) : t{x} { i = 2; }

接下来,我用一些其他的东西来扩展这个类,第一个(模板化的)构造函数所做的不仅仅是设置t

我想为T = FooT = Bar 做的所有事情。

有没有什么方法可以从专门的构造函数中调用模板化构造函数?

//This does not work, since it will create a delegation cycle
template <> Test<Foo>::Test(Foo* x) : Test(x) { i = 1; }
template <> Test<Bar>::Test(Bar* x) : Test(x) { i = 2; }

【问题讨论】:

    标签: c++ c++11 templates


    【解决方案1】:

    您可以为此使用delegating constructor

    您可以创建一个私有构造函数,它接受t 的指针和iint。然后你可以用它来设置xi,并运行所有的共享代码。

    看起来像:

    template <class T>
    class Test
    {
    public:
        Test(T* x) : Test(x, 0) { /*code for default case, runs after delegate*/ }
    private:
        Test(T* t, int i) : t(t), i(i) { /*code to run for everything*/ }
        const T* const t;
        int i;
    };
    
    template <> Test<Foo>::Test(Foo* x) : Test(x, 1) { /*code only for Foo, runs after delegate*/ }
    template <> Test<Foo>::Test(Bar* x) : Test(x, 2) { /*code only for Bar, runs after delegate*/ }
    

    委托构造函数能否成为通用/模板构造函数(与 Foo 和 Bar 的特定、专用构造函数具有相同的签名)?

    不,这是不可能的。当您特化一个函数模板时,您并没有创建一个新函数,而是指定如果 T 被推导出为您在特化中指定的类型,则使用特化定义代替泛型。

    这就是为什么我有“所有三个构造函数”(泛型和两个特化)调用Test(T* t, int i),它处理所有案例共享的代码。

    【讨论】:

    • 或者,可以使用一个虚拟参数(沿着std::nothrow 的行,它是空类型,仅用于选择特定的重载)
    • 所以,按照我想要的方式,委托构造函数 通用/模板化构造函数(并且与 Foo 和 Bar 的特定、专用构造函数具有相同的签名)... 这不可能吗?
    • @T.J.Evers 不,这是不可能的。当您特化一个函数模板时,您并没有创建一个新函数,而是指定如果 T 被推导出为您在特化中指定的类型,则使用特化定义代替泛型定义。这就是为什么我拥有所有“三个”,即泛型和两个特化,构造函数调用Test(T* t, int i),它处理所有情况下的代码。
    【解决方案2】:

    你考虑过继承吗?我想到的第一件事是创建一个从基类派生的Test 类,它将为 foo 和 bar 处理所有你想要的相同的东西。所以你可以在派生类(Test)中调用基类构造函数,然后只为Foobar做一些事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      相关资源
      最近更新 更多