C++ C++;方法签名相同但返回类型不同
我看到了以下代码:C++ C++;方法签名相同但返回类型不同,c++,templates,overloading,C++,Templates,Overloading,我看到了以下代码: 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:
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;
};
那么如何知道调用了哪一个呢?这两个函数实际上并不相同。只有第二个函数被声明为
const
成员函数。如果从中调用成员的对象是const
,则使用后一个选项。如果对象为非常量,则使用第一个选项
例如:
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
}
如果两个函数都声明为non-const
,或者都声明为const
,编译器将(无论如何)抱怨
为什么编译器不抱怨
T& value() {return m_value;}
T value() const {return m_value;}
因为常量
对不同的函数签名计数。您对函数签名相同的假设是错误的。标记为
const
的函数将为类型的任何const
实例或引用调用
如何知道调用了哪一个
在函数中放入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;
};
关于函数解析优先级的几句话。编译器通过以下方式区分常量/非常量函数:
如果一个类只有具有给定名称和参数列表的const函数,它将被常量和非常量对象调用。调用此函数后,对象将“假定”常量(即使它不是常量),这意味着该函数只能调用其他常量函数
如果一个类只有非常量函数,它将被非常量对象调用。尝试为常量对象调用此函数将导致编译错误
如果一个类同时具有这两个函数,常量版本将用于常量对象,非常量版本将用于非常量对象
感谢@owacoder让我注意到描述中的初始混淆。我认为第二段的逻辑是颠倒的。不能为const
对象调用非const
函数。@owacoder,我的错。你是对的,我误读了你的评论,错打了我的答案。将编辑它。是的,是的,是的@jaggedSpire是正确的,我只是略读,没有仔细阅读。这是罪过。在确定两个函数签名是否“相同”时,不要忽略关键字!
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();
}
const T& value() const {
std::cout << "const version" << std endl;
return m_value;
}
Type& operator=(const T& rhs) {value() = rhs; return *this;}