模板化类的专门继承会导致成员函数返回模板化类类型而不是继承类类型

时间:2018-02-13 16:33:34

标签: c++ c++11 templates inheritance overloading

假设我有这样一个基类:

template<typename T>
class Base {
public:
    Base& operator()(const T& value) {
        this->value = value;
        return *this;
    }
    T value;
};

现在我想继承这个类来创建特定于类型的类

class InheritedFloat : public Base<float> {} inheritedFloat;

现在,我尝试在功能中捕获这种继承:

void function(const InheritedFloat& inherited) {
    std::cout << inherited.value << '\n';
}

这样调用此函数当然可以正常工作:

int main() {
    function(inheritedFloat); //(inheritedFloat is a global instance)

    return 0;
}

但是当我尝试使用operator()(const float& value){...}成员函数调用它时,function(const InheritedFloat& inherited){...}并未将其视为InheritedFloat - 类型,而是Base<float>型:

int main() {
    function(inheritedFloat(10.f)); //error

    return 0;
}

错误:

Error   C2664   'void function(const InheritedFloat &)': cannot convert argument 1 from 'Base<float>' to 'const InheritedFloat &'

那么如何让operator()(const T& value){...}返回InheritedFloat&代替Base<float>&

为了进一步澄清,这只是一个简化的例子(当然)。我有几十个继承案例。所以我不能只是模板指定function()

template<typename T>
void function(const Base<T>& inherited) {
    std::cout << inherited.value << '\n';
}

因为每个继承都需要区别对待。类型会重叠,因此会有多个Base<std::size_t&gt;案例,例如。

整个代码:

#include <iostream>

template<typename T>
class Base {
public:
    Base& operator()(const T& value) {
        this->value = value;
        return *this;
    }
    T value;
};

class InheritedFloat : public Base<float> {} inheritedFloat;


void function(const InheritedFloat& inherited) {
    std::cout << inherited.value << '\n';
}

int main() {
    function(inheritedFloat(10.f));

    return 0;
}

感谢阅读,感谢您的帮助!

1 个答案:

答案 0 :(得分:10)

您可以在此处使用CRTP。通过提供额外的模板参数,您可以使基类函数返回对派生类的引用:

#include <iostream>

template<typename Derived, typename T>
class Base {
public:
    Derived & operator()(const T& value) {
        this->value = value;
        return *static_cast<Derived *>(this);
    }
    T value;
};

class InheritedFloat : public Base<InheritedFloat, float> {} inheritedFloat;


void function(const InheritedFloat& inherited) {
    std::cout << inherited.value << '\n';
}

int main() {
    function(inheritedFloat(10.f));

    return 0;
}

online compiler