在编译器生成的复制构造函数上强制模板化构造函数

sly*_*sly 0 c++ templates constructor c++11

采取以下,

template<class T>
struct Foo {
    Foo(){}

    // a template constructor "generalized" over related types
    template<class U>
    Foo(Foo<U> const&) {
        std::cout << 1;
    }

    // copy constructor
    Foo(Foo const&) {
        std::cout << 2;
    }
};
Run Code Online (Sandbox Code Playgroud)

及其用户:

void main() {
   Foo<int> f1;
   Foo<const int> f2(f1); // prints 1
   Foo<const int> f3(f2); // prints 2
}
Run Code Online (Sandbox Code Playgroud)

即使没有显式复制构造函数,编译器也会生成一个并使用它f3(f2).

有没有办法强制模板重载?例如,复制构造函数可以是SFINAE吗?这是为了避免代码重复,有趣的是,似乎没有办法使用委托构造函数(从复制构造函数委托给模板).

Pra*_*ian 5

构造函数模板永远不能是复制构造函数,因此如果您没有定义构造函数,编译器将隐式地为您执行此操作,如您所知.

避免代码重复的一种解决方法是定义第三个构造函数,并从上面显示的两个构造函数委托它.

template<class T>
struct Foo {
    Foo(){}

    struct tag{};

    // a template constructor "generalized" over related types
    template<class U>
    Foo(Foo<U> const& f)
    : Foo(tag{}, f)
    {
        std::cout << 1 << '\n';
    }

    // copy constructor
    Foo(Foo const& f) 
    : Foo(tag{}, f)
    {
        std::cout << 2 << '\n';
    }

private:
    template<class U>
    Foo(tag, Foo<U> const&)
    {
        std::cout << 3 << '\n';
    }
};
Run Code Online (Sandbox Code Playgroud)

现场演示

  • @sly我看不出SFINAE如何禁用复制构造函数.它不是模板,因此不涉及演绎,这对SFINAE来说是必要的. (2认同)