防止调用模板化复制构造函数

时间:2014-09-23 19:57:31

标签: c++ templates

在下文中,正在调用模板化复制构造函数。

#include <iostream>

using namespace std;

class A
{
public:
    A(){ cout << "Class A constructor\n";}
    A(const A &a){ cout << "Class A copy constructor\n"; }
};

class B : public A
{
public:
    B(){ cout << "Class B constructor\n";}
    B(const B &a){ cout << "Class B copy constructor\n"; }
};

template <typename T>
class Template
{
public:
    Template() { cout << "Template default\n"; }
    Template(const Template &a) { cout << "Template copy constructor\n"; }

    // This gets called
    template <typename T2>
    Template(const Template<T2> &a)
    {
        cout << "Templated template copy constructor\n";
    }

};

void funcT(const Template<A> &a)
{
}

int main()
{
    Template<B> bt;

    cout << "Calling funcT(bt)\n";
    funcT(bt);

    return 0;
}

如何防止模板化复制构造函数被调用?我期待由于B的类型为A,并且我通过引用传递,因此不会调用任何构造函数。我创建了一个专门的复制构造函数,希望它会被调用:

Template(const Template<A> &a)
{
    cout << "Specialized templated template copy constructor\n";
}

但那不会编译。

基本上,我打电话给funcT()时,我不想打电话给现有的三个构造函数。

2 个答案:

答案 0 :(得分:2)

您可以将您的功能设为接受任何Template<T> 的模板,但仅当 T继承自A时,才能进行复制/转换:

#include <type_traits>

template <typename T>
auto funcT(const Template<T>& a)
    -> typename std::enable_if<std::is_base_of<A, T>::value>::type
{
}

DEMO


  

我们没有使用C ++ 0x

您可以自己编写enable_ifis_base_of

template <bool b, typename T = void>
struct my_enable_if {};
template <typename T>
struct my_enable_if<true, T> { typedef T type; };
template <typename Base, typename Derived>
struct my_is_base_of
{
    static char test(Base*);    
    static long test(...);
    static const bool value = sizeof(test((Derived*)0)) == sizeof(char);
};

template <typename T>
typename my_enable_if<my_is_base_of<A, T>::value>::type funcT(const Template<T>& a)
{
}

C++98 DEMO

答案 1 :(得分:1)

仅仅因为B派生自A并不意味着Template<B>派生自Template<A>。根据您要完成的任务,模板功能可能有效:

template<typename T>void funcT(const Template<T> &a)
{
}
  

./ a.out的
  模板默认
  调用funcT(bt)

罗伯特