Должен ли я объявить операторы преобразования явным образом в C ++ 11?

В C ++ 11 рекомендуется:

  1. явно определить наши собственные конструкторы копирования / перемещения, чтобы компилятор не делал это сам (в соответствии с [1]).
  2. явно объявить конструкторы с одним аргументом как явные, чтобы избежать неявных преобразований (согласно [2]).

Стоит ли в этом ходу мысли объявлять операторов преобразования explicit помешать компилятору использовать их для выполнения неявных преобразований?

1

Решение

В C ++ 11 рекомендуется:

  1. явно определить наши собственные конструкторы копирования / перемещения, чтобы компилятор не делал это сам.

Кто бы ни придумал эту рекомендацию, это неправильно. Когда реализация по умолчанию соответствует вашим потребностям, используйте ее. Вы, вероятно, не получите это лучше сами.

  1. явное объявление конструкторов с одним аргументом как явных, чтобы избежать неявных преобразований.

Основные положения C ++ say «По умолчанию объявляем конструкторы с одним аргументом explicit«. В некоторых случаях вы можете предпочесть неявную конструкцию (например, std::string имеет от const char*). Оставьте explicit декларация в этих случаях.

Следует ли в этом цикле мысли объявлять операторы преобразования явными, чтобы компилятор не использовал их для выполнения неявных преобразований?

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

4

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

Ответ «нет, вы не должны». Операторы явного преобразования были добавлены в язык для решения конкретной проблемы, описанной ниже. Когда вы не имеете дело с этой конкретной проблемой, вы должны либо добавить явный конструктор копирования в целевой класс, либо написать именованную функцию вместо оператора преобразования (как в c_str() из std::string).

Давайте сделаем шаг назад и рассмотрим конверсию в целом. Когда вам нужно написать код для перехода из A в B у вас есть два варианта — вы можете определить конструктор с одним аргументом, как это

struct B {
B(const A& a);
};

или вы можете определить оператор преобразования, например так:

struct A {
operator B() const;
};

Первый подход позволил явное / неявное управление до C ++ 11. Тем не менее, он не был доступен в двух ситуациях:

  • Вы свой тип A но у вас нет собственного типа B, или же
  • Вы свой тип A, но типа B является примитивный

Согласно черновик для операторов явного преобразования C ++ 11 именно эти два случая рассматривал комитет, когда они выступали за добавление оператора явного преобразования в язык. Все другие ситуации уже были охвачены (1) неявными и неявными конструкторами копирования, (2) операторами неявного преобразования и (3) именованными функциями-членами.

3

По вопросам рекламы ammmcru@yandex.ru