如何在不添加/删除 mem 函数的“const”性的情况下重载 getter 函数?
How to overload getter functions without adding/ removing `const`ness of mem function?
我想不通,为什么 C++ 不允许根据 return 类型进行重载,如下例所示
三个成员(getter)函数具有不同的函数签名甚至何时存储
指向成员函数的指针,我们需要不同的内存函数指针类型,例如:
for instance T = std::string
using constRefPtr = const std::string&(MyStruct::*)() const;
using constValuePtr = const std::string(MyStruct::*)() const;
using valuePtr = std::string(MyStruct::*)() const;
我读过这个 similar post,其中建议使用 const 和 non-cost
成员函数。
问题:如何在不删除 const
ness 的情况下使以下 (getter) 重载工作
每个成员函数(如果可以通过标准 C++)?
我正在使用 C++17。
#include <iostream>
#include <string>
template<typename T> class MyStruct
{
T m_val;
public:
explicit MyStruct(const T& value)
: m_val(value)
{}
const T& getVal() const { return m_val; } // get val as const ref(no copy of member)
const T getVal() const { return m_val; } // get a const member as return
T getVal() const { return m_val; } // get a copy of member
};
int main()
{
MyStruct<std::string> obj{"string"};
const auto& val_const_ref = obj.getVal(); // overload const std::string& getVal() const
const auto val_const = obj.getVal(); // overload const std::string getVal() const
auto val = obj.getVal(); // overload std::string getVal() const
return 0;
}
我收到的错误信息:
error C2373 : 'MyStruct<T>::getVal' : redefinition; different type modifiers
note: see declaration of 'MyStruct<T>::getVal'
note: see reference to class template instantiation 'MyStruct<T>' being compiled
error C2059 : syntax error : 'return'
error C2238 : unexpected token(s) preceding ';'
error C2143 : syntax error : missing ';' before '}'
error C2556 : 'const T MyStruct<T>::getVal(void) const' : overloaded function differs only by return type from 'const T &MyStruct<T>::getVal(void) const'
1 > with
1 > [
1 > T = std::string
1 > ]
1 > C:\Z Drive\CPP Programs\Visual Studio Project\Main.cc(62) : note: see declaration of 'MyStruct<std::string>::getVal'
note: see reference to class template instantiation 'MyStruct<std::string>' being compiled
error C2373 : 'MyStruct<std::string>::getVal' : redefinition; different type modifiers
note: see declaration of 'MyStruct<std::string>::getVal'
error C2059 : syntax error : 'return'
error C2238 : unexpected token(s) preceding ';'
error C2146 : syntax error : missing ';' before identifier 'T'
error C2530 : 'val_const_ref' : references must be initialized
error C2789 : 'val_const' : an object of const - qualified type must be initialized
note: see declaration of 'val_const'
Question: How could I make the following (getter)overloads work without removing constness of each member functions(if it is possible through standard C++)?
适当地命名它们。正如@Slava 指出的那样,当 return 复制值时,区分 T
和 const T
毫无意义,所以类似:
const T& getConstRefVal() const { return m_val; } // get val as const ref(no copy of member)
T getVal() const { return m_val; } // get a copy of member
你只是...不能在 return 类型上超载,句号。
您可以创建两个不同名称的函数:
T const& ref() const { return m_val; }
T val() const { return m_val; }
哪些 自身 可以根据 const
ness 或 &
ness 重载:
T const& ref() const { return m_val; }
T& ref() { return m_val; }
T val() const& { return m_val; }
T val() && { return std::move(m_val); }
这是不可能的。您不能重载 return 类型。重载解析考虑了函数签名。函数签名由以下部分组成:
- 函数名称
- cv-qualifiers
- 参数类型
标准说:
1.3.11签名
the information about a function that participates in overload
resolution (13.3): its parameter-type-list (8.3.5) and, if the
function is a class member, the cv-qualifiers (if any) on the function
itself and the class in which the member function is declared. [...]
(根据 Luchian Grigore's answer 稍作编辑)
我想不通,为什么 C++ 不允许根据 return 类型进行重载,如下例所示 三个成员(getter)函数具有不同的函数签名甚至何时存储 指向成员函数的指针,我们需要不同的内存函数指针类型,例如:
for instance T = std::string
using constRefPtr = const std::string&(MyStruct::*)() const;
using constValuePtr = const std::string(MyStruct::*)() const;
using valuePtr = std::string(MyStruct::*)() const;
我读过这个 similar post,其中建议使用 const 和 non-cost 成员函数。
问题:如何在不删除 const
ness 的情况下使以下 (getter) 重载工作
每个成员函数(如果可以通过标准 C++)?
我正在使用 C++17。
#include <iostream>
#include <string>
template<typename T> class MyStruct
{
T m_val;
public:
explicit MyStruct(const T& value)
: m_val(value)
{}
const T& getVal() const { return m_val; } // get val as const ref(no copy of member)
const T getVal() const { return m_val; } // get a const member as return
T getVal() const { return m_val; } // get a copy of member
};
int main()
{
MyStruct<std::string> obj{"string"};
const auto& val_const_ref = obj.getVal(); // overload const std::string& getVal() const
const auto val_const = obj.getVal(); // overload const std::string getVal() const
auto val = obj.getVal(); // overload std::string getVal() const
return 0;
}
我收到的错误信息:
error C2373 : 'MyStruct<T>::getVal' : redefinition; different type modifiers
note: see declaration of 'MyStruct<T>::getVal'
note: see reference to class template instantiation 'MyStruct<T>' being compiled
error C2059 : syntax error : 'return'
error C2238 : unexpected token(s) preceding ';'
error C2143 : syntax error : missing ';' before '}'
error C2556 : 'const T MyStruct<T>::getVal(void) const' : overloaded function differs only by return type from 'const T &MyStruct<T>::getVal(void) const'
1 > with
1 > [
1 > T = std::string
1 > ]
1 > C:\Z Drive\CPP Programs\Visual Studio Project\Main.cc(62) : note: see declaration of 'MyStruct<std::string>::getVal'
note: see reference to class template instantiation 'MyStruct<std::string>' being compiled
error C2373 : 'MyStruct<std::string>::getVal' : redefinition; different type modifiers
note: see declaration of 'MyStruct<std::string>::getVal'
error C2059 : syntax error : 'return'
error C2238 : unexpected token(s) preceding ';'
error C2146 : syntax error : missing ';' before identifier 'T'
error C2530 : 'val_const_ref' : references must be initialized
error C2789 : 'val_const' : an object of const - qualified type must be initialized
note: see declaration of 'val_const'
Question: How could I make the following (getter)overloads work without removing constness of each member functions(if it is possible through standard C++)?
适当地命名它们。正如@Slava 指出的那样,当 return 复制值时,区分 T
和 const T
毫无意义,所以类似:
const T& getConstRefVal() const { return m_val; } // get val as const ref(no copy of member)
T getVal() const { return m_val; } // get a copy of member
你只是...不能在 return 类型上超载,句号。
您可以创建两个不同名称的函数:
T const& ref() const { return m_val; }
T val() const { return m_val; }
哪些 自身 可以根据 const
ness 或 &
ness 重载:
T const& ref() const { return m_val; }
T& ref() { return m_val; }
T val() const& { return m_val; }
T val() && { return std::move(m_val); }
这是不可能的。您不能重载 return 类型。重载解析考虑了函数签名。函数签名由以下部分组成:
- 函数名称
- cv-qualifiers
- 参数类型
标准说:
1.3.11签名
the information about a function that participates in overload resolution (13.3): its parameter-type-list (8.3.5) and, if the function is a class member, the cv-qualifiers (if any) on the function itself and the class in which the member function is declared. [...]
(根据 Luchian Grigore's answer 稍作编辑)