使用std :: enable_if启用模板化构造函数和返回另一个模板化实例的函数

时间:2017-04-05 14:16:18

标签: c++ c++11 templates enable-if

我想创建一个模板化的类MyClass<T>,我希望有一个模板化的构造函数,它将采用MyClass<U>类型的单个参数,只有U是{派生自T(或与T相同,在这种情况下基本上也充当复制构造函数)。如果不是,我想在编译时失败。此外,它将具有第二个模板化成员函数MyClass<U> convert<U>() const,仅当U派生自T(或与T相同时)才有效。这个函数的实际实现在这个时候并不重要,现在我只想弄清楚如何声明它们。

虽然在某些情况下,可以使用仅static_assert std::is_base_of而不std::enable_if的{​​{1}}来使编译失败,但我想知道我是否可以实现使用std :: enable_if。

稍微强一些

提前致谢

1 个答案:

答案 0 :(得分:0)

具有不同模板参数的类模板中的模板化构造函数

您将在此处讨论第一个问题。 由于您无法明确指定构造函数的模板参数,因此必须从参数本身推断出它。

我现在已经尝试了一段时间,因为我很好奇,显然后续的代码无法正常工作:

class A {
    public:
        inline static std::string print() { return "A"; }    
};

class B 
    : public A {
    public:
        // Consciously hidden parent "print()"
        inline static std::string print() { return "B"; }
};

template <typename T>
class MyClass {
    public:

    explicit MyClass() {
        std::cout << "Default of MyClass with " << T::print() << std::endl;
    }

    template <typename U>
    MyClass(const typename std::enable_if<std::is_base_of<T, typename 
U::internal_type>::value, U>::type& other) {
        std::cout << "Copy constructor of equal or derived type!" << 
U::internal_type::print() << std::endl;
    }

    typedef T internal_type;
};

int main()
{ 
    MyClass<A> a;
    MyClass<B> b;
    MyClass<A> cpa(a);
    MyClass<A> cpb(b); // Error
}

重要的是这个:

template <typename U>
    MyClass(const typename std::enable_if<std::is_base_of<T, typename U::internal_type>::value, U>::type& other) {
        std::cout << "Copy constructor of equal or derived type!" << 
U::internal_type::print() << std::endl;
    }

我定义了internal_type帮助器来执行对带有T = B 参数的 MyClass的MyClass-template参数的检查,这就出现了问题:

通常,我们从外部提供U,如果没有它,就不要做一些enable_if魔术。 在这种情况下,我们传递MyClass而没有任何关于U的信息,但是尝试从U中获取信息......

这至少是我现在从试图理解它的方式。

如果有效,则部分:

std::is_base_of<T, typename U::internal_type>::value
在我们的案例中,

将被替换为

std::is_base_of<A, B>::value

应该给出真实的。 如果依次启用,则应该使用&#34; U&#34;,即MyClass并用它替换整个事物,相当于:

MyClass<A> {
    //...
    MyClass(const MyClass<B>& other) {
    }
};

所以我认为至少构造函数是不可能的。

如果我错了并需要了解更多信息,那么模板元编程大师会纠正我:D