Как перегрузить функции получения без добавления / удаления `const`ness функции mem? - PullRequest
0 голосов
/ 23 мая 2019

Я не мог понять, почему C ++ не разрешает перегрузку в соответствии с типом возвращаемого значения, как в следующем случае функция трех членов (получатель) имеет различную сигнатуру функции и даже когда хранить Для указателя на функцию-член нам нужны разные типы указателей на функции mem, такие как:

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;

Я прочитал аналогичный пост , где было предложено иметь постоянный и бесплатный функции-члены.

Вопрос: Как сделать так, чтобы следующие (getter) перегрузки работали без удаления const ness каждого члена-функции (если это возможно через стандартный 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'

Ответы [ 3 ]

4 голосов
/ 23 мая 2019

Вы просто ... не можете перегрузить тип возвращаемого значения, полный останов.

Вы можете просто сделать две функции с разными именами:

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); }
2 голосов
/ 23 мая 2019

Это невозможно.Вы не можете перегружать тип возвращаемого значения.Разрешение перегрузки учитывает сигнатуру функции.Сигнатура функции состоит из:

  • имени функции
  • cv-квалификаторов
  • типов параметров

Стандарт гласит:

1.3.11 подпись

информация о функции, которая участвует в разрешении перегрузки (13.3): ее список типов параметров (8.3.5) и, если функция является членом класса, cv-квалификаторы (если таковые имеются) для самой функции и класса, в котором объявлена ​​функция-член.[...]

(Слегка отредактировано с Ответ Лучиана Григоре )

0 голосов
/ 23 мая 2019

Вопрос: Как я могу заставить следующие (getter) перегрузки работать, не удаляя константность каждой функции-члена (если это возможно через стандартный C ++)?

Назовите их соответствующим образом. И, как указывает @Slava, при возврате скопированного значения нет смысла различать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...