2017-01-25 4 views
2

Я пытаюсь реализовать хак, где я пытаюсь перегрузить return. Я позволю коду поговорить.C++ Перегрузка оператора преобразования hack

namespace tcn 
{ 
    class foo 
    { 
     std::string blah; 

    public: 
     class proxy 
     { 
      int intval; 
      std::string strval; 
     public: 
      proxy(int intv, std::string strv) : intval(intv), strval(strv) {}; 
      operator int() const { return intval; } 
      operator std::string() const { return strval; } 

     }; 

     foo(); 
     ~foo(); 

     proxy get(); 
    }; 

    foo::foo() 
    { 
     // Create stuff // 
    } 

    foo::~foo() 
    { 
     // Destroy stuff // 
    } 

    foo::proxy foo::get() 
    { 
     int intval = 911; 
     std::string strval = "Hello!?"; 

     proxy temp(intval, strval); 

     return temp; 
    } 
} 



int main() 
{ 
    tcn::foo bar; 

    std::string ts = bar.get(); // OK 
    int ti = bar.get(); // OK 

    ti = bar.get(); // OK 

    ts = bar.get(); // Compile error here 

    return 0; 
} 

Если я пытаюсь скомпилировать код, он выдает ошибку, как следующий

error: ambiguous overload for 'operator=' (operand types are 'std::string {aka std::basic_string}' and 'tcn::foo::proxy')
ts = bar.get();

мне было интересно, как это преодолеть. Я видел другие способы реализовать это, используя «подсказки», но я пытаюсь дать пользователю легкий интерфейс. Поэтому я ищу простое назначение со стороны пользователя. Как еще это можно реализовать?

Благодарим вас за это, и если это будет выглядеть, прошу прощения. Я не так хорош в C++.

+3

Вместо предоставления неявных преобразований просто имеют геттеры (и сеттеры) с разными именами для разных типов. Это разумно, так как в большинстве случаев программист, записывающий вызывающую функцию, будет знать, что является требуемым типом, и иметь возможность выбирать требуемый getter/setter по имени. – Peter

+0

Примечание: только ошибки на GCC (возможно, и Clang), а не на MSVC (неожиданное удивление). –

+1

OP, явное приведение в действие, однако, компилятор не может различать. 'ts = static_cast (bar.get());' –

ответ

2

Звонок неоднозначно, потому что у std::string::operator= есть перегрузки std::string и char. Оба они могут быть вызваны с использованием tcn::proxy: первый с использованием оператора преобразования std::string, а второй с использованием оператора преобразования int, за которым следует интегральное преобразование.

Обычно разрешение на перегрузку предпочло бы неявную последовательность преобразований без необходимых стандартных преобразований по сравнению с теми, которые требуют интегрального преобразования, но этот выбор учитывается только в том случае, если две последовательности преобразования проходят через одну и ту же функцию. Поскольку у вас есть два отдельных пути, проходящих через две разные функции, вызов неоднозначен.

Решение состоит в том, чтобы не использовать интегральные преобразования для таких вещей; это просто приводит к странным крайним случаям, неожиданному поведению и скрытым ошибкам.

+0

Так почему же наш любимый MSVC не жалуется? –

+0

@ GillBates Поскольку MSVC: p – TartanLlama

Смежные вопросы