将模板化基类转换运算符引入派生范围

时间:2018-05-23 16:52:31

标签: c++ templates

我有一个定义约束模板化转换运算符的基类

struct base {
    template <typename C, std::enable_if_t<some_constraints<C>, int> = 0>
    operator C() const;
};

我还有一个派生类,它实现了另一个具有不同约束的转换运算符:

struct derived : base {
    template <typename P, std::enable_if_t<different_constraints<P>, int> = 0>
    operator P() const;
};

不幸的是,派生类中的声明隐藏了基类中的运算符。我想将基本运算符引入派生范围,但是显而易见的&#34;语法

template <typename C>
using base::operator C;

不起作用(编译器似乎试图将其解析为别名模板声明)。

有没有人知道实现此目的的正确语法?

4 个答案:

答案 0 :(得分:1)

我会说这是不可能的。即使它是,你的派生运算符也会隐藏基数,因为模板参数不属于namespace.udecl#15.sentence-1

  

当using-declarator将基类的声明带入派生类时,派生类中的成员函数和成员函数模板覆盖和/或隐藏具有相同名称的成员函数和成员函数模板,parameter-type-list基类中的cv-qualification和ref-qualifier(如果有的话)(而不是冲突的)

很遗憾,模板参数不计算,且转化operator都有空参数类型列表,const且没有参考限定符。

答案 1 :(得分:1)

以下技巧需要GNU g ++,使用C ++ 14。

如果some_constraintsdifferent_constraints互斥,您可以在using base::operator auto;课程中添加derived,以使base的所有转化运算符都可用。

示例:

struct Base {
protected:
    // conversion to pointer types (protected).
    template<typename T, typename= typename std::enable_if<std::is_pointer<T>::value>::type>
    operator T() const;
};

struct Derived : public Base{
    // Make all Base conversion operators public.
    using Base::operator auto;

    // conversion to default constructible & non-pointer types.
    // added an extra typename=void to distinguish from Base template operator.
    template<typename T, typename= typename std::enable_if<!std::is_pointer<T>::value>::type,typename=void>
    operator T() const;
};

Live demo

答案 2 :(得分:1)

要达到类似的效果,您可以在运算符内部移动约束,如果不满足约束,可以调用基本转换运算符:

struct base {
    template <typename C, std::enable_if_t<some_constraints<C>, int> = 0>
    operator C() const;
};

struct derived : base {
    template <typename P>
    operator P() const {
        if constexpr (different_constraints<P>) {
            // Overridden operator
        } else {
            return base::operator P();
        }
    }
};

或者等效地有一个常规的std::enable_if_t<different_constraints<P>, int> = 0转换操作符和另一个std::enable_if_t<!different_constraints<P>, int> = 0来调用基本转换操作符。

答案 3 :(得分:0)

有时您可以使用转换构造函数“解决”此问题-但这并非总是可能的(例如转换为指针T)。