【问题标题】:Specialized inheritance of a templated class causes member function to return templated class type rather than inherited class type模板类的特殊继承导致成员函数返回模板类类型而不是继承的类类型
【发布时间】:2018-02-13 16:33:34
【问题描述】:

假设我有一个这样的基类:

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&amp; value){...} 成员函数调用它时,function(const InheritedFloat&amp; inherited){...} 不会将其视为InheritedFloat-Type,而是将其视为Base&lt;float&gt;-Type:

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&amp; value){...} 返回InheritedFloat&amp; 而不是Base&lt;float&gt;&amp;


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

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

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

整个代码:

#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;
}

感谢阅读,感谢任何帮助!

【问题讨论】:

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


    【解决方案1】:

    您可以在此处使用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

    【讨论】:

    • 是的,我也尝试过,但我错过了*static_cast&lt;Derived *&gt;(this)。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2019-09-02
    相关资源
    最近更新 更多