在C ++中调用基类模板构造函数

时间:2017-04-01 22:19:22

标签: c++ templates inheritance constructor

我有一个模板基类,它有一个构造函数,用于从该类的任何其他模板实例化转换,如下所示:

template <class T>
class FooBase
{
public:

    FooBase()
    {
    }

    template <class U>
    FooBase(const FooBase<U>& other)
    {
        std::cout << "FooBase<U>" << std::endl;
    }
};

注意没有定义复制构造函数。

然后我有一个派生模板类,它有一个复制构造函数,以及用于转换的构造函数:

template <class T>
class Foo : public FooBase<T>
{
public:

    Foo()
    {
    }

    Foo(const Foo& other) :
        FooBase<T>(other)
    {
    }

    template <class U>
    Foo(const Foo<U>& other) :
        FooBase<T>(other)
    {
    }
};

由于FooBase没有复制构造函数,因此FooBase<T>(other)会调用编译器生成的复制构造函数。这意味着如果我运行这个:

int main()
{
    Foo<int> a;
    Foo<int> b(a);

    return 0;
}

输出为,应为FooBase<U>

当然,我可以尝试通过在FooBase中创建一个复制构造函数并使用delegating constructors来解决问题:

    FooBase(const FooBase& other)
        : FooBase<T>(other)
    {
    }

但不幸的是,它不起作用,并且会导致递归调用,因为编译器有用地指出:

warning C4717: 'FooBase<int>::FooBase<int>': recursive on all control paths, function will cause runtime stack overflow

因此唯一的解决方案是将逻辑复制到两个构造函数中。

有没有办法解决代码重复或单独的初始化函数?

1 个答案:

答案 0 :(得分:4)

您可以拥有第三个私有构造函数,复制构造函数和构造函数模板都委托给它,并且包含实际工作:

template <typename T> class FooBase
{
    struct Tag{};

    template <typename U>  // May have U = T
    FooBase(Tag, const FooBase<U> & rhs)
    {
        // actual implementation
    }

public:
    FooBase(const FooBase & rhs) : FooBase(Tag(), rhs) {}

    template <typename U>  // Never selects U = T
    FooBase(const FooBase<U> & rhs) : FooBase(Tag(), rhs) {}
};
相关问题