Разница между возвращаемым значением и локальной переменной

Предположим, у меня есть

#include <string>

class A
{
public:
template<class T>
operator T();

A child();
};

void f()
{
A a;
std::string s1 = a;            // ok
std::string s2 = a.child();    // error (line 34)

s1 = a;           // error (line 36)
s2 = a.child();   // error (line 37)

}

Конструктор std :: string может принимать ссылку char * или std :: string, поэтому назначение неоднозначно. Но почему мой компилятор (VC ++ 10) жалуется на второе назначение, а не первое?

Я ищу способ отдать приоритет оператору преобразования шаблона, а не перегруженному конструктору.

Я получаю следующие ошибки:

1>------ Build started: Project: Plasma4Test, Configuration: Debug Win32 ------
1>  Plasma4Test.cpp
1>d:\bitbucket\vx\projects\plasma4test\plasma4test.cpp(34): error C2440: 'initializing' : cannot convert from 'A' to 'std::basic_string<_Elem,_Traits,_Ax>'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          No constructor could take the source type, or constructor overload resolution was ambiguous
1>d:\bitbucket\vx\projects\plasma4test\plasma4test.cpp(36): error C2593: 'operator =' is ambiguous
1>          c:\program files\microsoft visual studio 10.0\vc\include\xstring(772): could be 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(_Elem)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xstring(767): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const _Elem *)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xstring(762): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const std::basic_string<_Elem,_Traits,_Ax> &)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          while trying to match the argument list '(std::string, A)'
1>d:\bitbucket\vx\projects\plasma4test\plasma4test.cpp(37): error C2593: 'operator =' is ambiguous
1>          c:\program files\microsoft visual studio 10.0\vc\include\xstring(772): could be 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(_Elem)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xstring(767): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const _Elem *)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xstring(762): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const std::basic_string<_Elem,_Traits,_Ax> &)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xstring(707): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(std::basic_string<_Elem,_Traits,_Ax> &&)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          while trying to match the argument list '(std::string, A)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

7

Решение

Это похоже на ошибку VC10 для меня, и это не относится в std::string,

ОШИБКА ИЗОЛЯЦИИ:

Я привел это к следующему примеру:

#include <string>

class B
{
public:
B(char const*) { }
B(B&&) { }
};

class A
{
public:
operator char* const () { return 0; }
operator B () { return B(0); }
};

int main()
{
A a;
B b1 = a; // fine
B b2 = A(); // error C2440: 'initializing' : cannot convert from 'A' to 'B'
// No constructor could take the source type, or constructor
// overload resolution was ambiguous.
}

Учебный класс B имеет конструктор перемещения и конструктор, который принимает const char*, При попытке инициализировать b2 из rvalueVC10, похоже, не может выбрать оператора преобразования в B,

И Clang 3.2, и GCC 4.7.2 выбирают оператор преобразования в B,

СТАНДАРТНЫЕ ПРАВИЛА C ++:

Пункт 8.5 / 16 Стандартных мандатов C ++:

[для этого случая инициализации копирования,] «определяемые пользователем последовательности преобразования, которые можно преобразовать из исходного типа к типу назначения или (когда используется функция преобразования) для ее производного класса нумеруются, как описано в 13.3.1.4, и лучший выбирается с помощью разрешения перегрузки (13.3) «

Если мы рассмотрим все доступные последовательности преобразования в нашем примере из типа источника (A) к типу назначения (B), то тот, который включает в себя Aпользовательская функция преобразования в char const* требует в дальнейшем преобразование (сделано через Bконструктор, который принимает char const*) для того, чтобы достичь тип назначения B, Таким образом, это на один шаг дольше, чем тот, который использует Aпользовательская функция преобразования в B (согласно 13.3.3.2), что делает последний предпочтительным.

Это, кажется, подтверждает, что это ошибка VC10.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]