简体   繁体   English

C ++相同的方法签名但返回类型不同

[英]C++ identical method signature but different return type

I have seen the following code: 我看过以下代码:

template <class T>
class Type {
    public:
        Type() {}
        T& operator=(const T& rhs) {value() = rhs; return value();}
        T& value() {return m_value;}
        T value() const {return m_value;}
    private:
        T m_value;
};

Why does the compiler not complain about 为什么编译器不抱怨

    T& value() {return m_value;}
    T value() const {return m_value;}

and how to know which one is invoked? 以及如何知道调用哪一个?

The two functions are actually not the same. 这两个功能实际上并不相同。 Only the second function is declared as a const member function. 只有第二个函数被声明为const成员函数。 If the object that the member is called from is const , the latter option is used. 如果调用该成员的对象是const ,则使用后一个选项。 If the object is non- const , the first option is used. 如果对象是非const ,则使用第一个选项。

Example: 例:

void any_func(const Type *t)
{
    something = t->value(); //second `const` version used
}

void any_func2(Type *t)
{
    something = t->value(); //first non-`const` version used
}

If both functions were declared non- const or both were declared const , the compiler would (should, anyway) complain. 如果这两个函数被宣布不const或两者被宣布为const ,编译器 (应,反正)抱怨。

Why does the compiler not complain about 为什么编译器不抱怨

Because the const counts for a different function signature. 因为const计算不同的函数签名。 Your assumption the function signatures are identical is wrong. 你假设函数签名是相同的是错误的。
The function marked as const will be invoked for any const instance or reference of Type<T> . 标记为const将为Type<T>任何const实例或引用调用。

and how to know which one is invoked? 以及如何知道调用哪一个?

Put a cout statement in the functions and test the following cases: 在函数中放置一个cout语句并测试以下情况:

template <class T>
class Type {
    public:
        Type() {}
        T& operator=(const T& rhs) {value() = rhs; return value();}
        T& value() { 
            std::cout << "non const version" << std endl;
            return m_value;
        }
        T value() const { 
            std::cout << "const version" << std endl;
            return m_value;
        }
    private:
        T m_value;
};

int main() {
    Type<int> t;
    t.value();

    Type<int> rt = t;
    rt.value();

    Type<int>* pt = &t;
    pt->value();

    const Type<int> ct;
    ct.value();

    const Type<int>& crt = t;
    crt.value();

    const Type<int>* pct = &t;
    pct->value();
}

Your assignment operator will call the non const version. 赋值运算符将调用非const版本。


The const version should better look like const版本应该更好看

const T& value() const { 
     std::cout << "const version" << std endl;
     return m_value;
}

because you can't always rely on RVO (return value optimization), and extra copies might be taken (especially for older compiler implementations). 因为您不能总是依赖RVO(返回值优化),并且可能会采用额外的副本(特别是对于较旧的编译器实现)。


Also note the assignment operator should return a reference to the current instance: 另请注意赋值运算符应返回对当前实例的引用:

 Type& operator=(const T& rhs) {value() = rhs; return *this;}

A couple of words on functions resolution priority. 关于功能解析优先级的几个词。 Compiler distinguishes between const/non const functions on following way: 编译器通过以下方式区分const /非const函数:

If a class has only const function with given name and argument list, it will be called for constant and non-constant objects alike. 如果一个类只有const函数和给定的名称和参数列表,那么它将被调用为常量和非常量对象。 After calling this function, object will 'assume' constness (even if it was not const), meaning that the function can only call other const functions. 在调用此函数之后,对象将“假定”constness(即使它不是const),这意味着该函数只能调用其他const函数。

If a class has only non-const function, it will be called for non-const objects. 如果一个类只有非const函数,那么它将被调用非const对象。 Attempt to call this function for const objects will lead to compilation error. 尝试为const对象调用此函数将导致编译错误。

If a class has both functions available, const version will be used for const objects, non-const version will be used for non-const objects. 如果一个类有两个可用的函数,const版本将用于const对象,非const版本将用于非const对象。

Thanks to @owacoder for pointing my attention to initial mixup in the description. 感谢@owacoder将我的注意力集中在描述中的初始混音上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM