Оператор явного преобразования и шаблонного преобразования - PullRequest
1 голос
/ 10 ноября 2011

Я хотел как-то расширить тип Microsoft _variant_t, чтобы он принимал неявные / явные преобразования в / из дополнительных типов.Для этого я написал следующий класс:

class value_type
{
  public:
    /* Constructors */
    value_type(const std::string& str) : m_variant(str.c_str()) {}
    template <typename Type> value_type(const Type& value) : m_variant(value) {}

    /* Conversion operators */
    operator const _variant_t&() const { return m_variant; }
    operator std::string() const { return static_cast<const char*>(m_variant); }
    template <typename Type> operator Type() const { return static_cast<Type>(m_variant); }
  private:
    _variant_t m_variant;
};

То есть, если каждый экземпляр _variant_t в коде заменяется на value_type, он "работает" то же самое.

Давайте рассмотрим следующую функцию, которая возвращает _variant_t:

_variant_t foo();

Если я напишу:

std::string bar()
{
  value_type v = foo();
  return v;
}

Он прекрасно компилируется.

Но если я изменю предыдущий код следующим образом:

std::string bar()
{
  return value_type(foo());
}

или:

std::string bar()
{
  return static_cast<std::string>(value_type(foo()));
}

Компиляция завершится неудачно со следующим сообщением:

configuration.cpp (41): ошибка C2668: 'std :: basic_string <_Elem, _Traits, _Ax> :: basic_string': неоднозначный вызов перегруженной функции

Если удалить строку template <typename Type> operator Type...все компилируется.

Теперь я понимаю, что говорит компилятор (он не знает, какой оператор использовать), но я не понимаю, почему: Казалось бы логично использовать operator std::string при преобразовании в std::string.Чего мне не хватает?

Спасибо.

1 Ответ

1 голос
/ 10 ноября 2011

Проблема в том, что конструктор строки перегружен. Таким образом, если возвращение включает в себя вызов строкового конструктора, то существует несколько вариантов: аргумент может быть преобразован в const char*, allocator<char> или string.

static_cast<string>(x) совпадает с string(x).

Полагаю, ваш первый ошибочный пример должен читать return string(foo());, а не return value_type(foo());

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...