Подтвердить что ты не робот

Изменения поведения оператора С++ 11 vs С++ 98?

Я хочу использовать некоторые функции С++ 11 в некоторых существующих проектах на С++, поэтому я начал менять флаги компиляции в Clang для некоторых проектов, и я постоянно сталкиваюсь с конкретной проблемой, связанной с обработкой конверсий С++ 11 (или операторов трансляции), которые я не ожидал увидеть, и не понимаю, почему это теперь считается ошибкой, когда это был допустимый код С++, а не С++ 11

Я проглотил это до простого примера:

#include <iostream>
#include <vector>

class SerializableFormat
{
public:
    size_t i;
};

class A
{
public:
    size_t x, y;

    A(size_t n) : x(n), y(1) { }

    operator const SerializableFormat() const
    {
        SerializableFormat result;

        result.i = x;

        if (y)
        {
            result.i /= y;
        }

        return result;
    }
};

int main(int argc, const char * argv[])
{
    std::vector<SerializableFormat> v;

    for(size_t i = 0; i < 20; i++)
    {
        v.push_back(A(i));
    }

    return 0;
}
  • Если флаги компиляции Clang установлены в -std=c++98 и libstdc++, проблем нет, и это компилируется отлично.
  • Если флаги компиляции Clang установлены на -std=c++11 и libc++, я получаю сообщение об ошибке No viable conversion from 'A' to 'value_type' (aka 'SerializableFormat')

Просто, чтобы было ясно - если вы думаете о предоставлении SerializableFormat конструктора только для класса A:

Поскольку класс SerializableFormat более подходит для преобразования в и из разных классов, имеет смысл для A (и других классов, которые хотят быть сериализуемыми), чтобы иметь конструкторы и операторы преобразования, а не ожидать SerializableFormat до охватывают все типы классов, которые хотят быть сериализуемыми, поэтому изменение SerializableFormat на наличие специального конструктора не является решением.

Может ли кто-нибудь увидеть, что я делаю неправильно здесь?

4b9b3361

Ответ 1

Как правильно отмечают комментарии, вы можете получить компиляцию, отбросив const в возвращаемом типе вашего оператора преобразования SerializableFormat:

operator const SerializableFormat() const

Что касается того, является ли clang правильным в этом поведении, это вопрос некоторого спора. Этот вопрос отслеживается сообщением об ошибке 16772. В настоящее время идет речь о создании отчета о выпуске CWG (С++ Committee), но это еще не сделано. Я отмечаю, что этот отчет об ошибке был открыт некоторое время (2013-07-23), но был обновлен еще в 2015-01-28 годах.

Тем временем, практические советы просто никогда не возвращаются на const -value. Это был достойный совет для С++ 98/03, но с семантикой перемещения становится плохой совет, потому что он отключит семантику перемещения.