В этом случае я бы также рекомендовал конструктор explicit
, потому что я думаю, что произвольная строка (которую принимает ваш конструктор) не моделирует число (которое моделирует ваш CBigInt
класс). Для таких случаев и предназначен explicit
.
Однако это не будет работать в случаях, когда используется прямая инициализация
struct A {
CBigInt n;
A():n(0) { } // ambiguity again
};
Как правило, explicit
не следует использовать для устранения внутренних неопределенностей. Его следует просто использовать для запрета преобразования из одного типа в другой, но не для предпочтения другого конструктора по сравнению с конструктором explicit
. Фактически, новые унифицированные инициализации C ++ 0x не игнорируют конструкторы explicit
в контексте инициализации копирования:
CBigInt f() {
return { 0 }; // still ambiguous
}
CBigInt b = { 0 }; // still ambiguous
Правила для равномерной инициализации таковы: оба конструктора рассматриваются, но если выбран явный конструктор, инициализация некорректна.
Буквально 0
является int
. Предполагая, что вы хотите принимать все целочисленные типы, вам нужно как минимум добавить int
принимающий конструктор. Вам не нужно добавлять перегрузки для целочисленных типов, меньших int
, потому что эти типы предпочитают int
другим целочисленным преобразованиям или указателям. Предполагая, что у вас есть перегрузка int
, вам также необходимо добавить перегрузки для оставшихся целочисленных типов и, если доступно, и использовать его, long long
и unsigned long long
. Двусмысленности больше не возникнет:
CBigInt (int);
CBigInt (unsigned int);
CBigInt (long);
CBigInt (unsigned long);
// CBigInt (long long);
// CBigInt (unsigned long long);
explicit CBigInt (const char *);