Я пытаюсь создать оператор преобразования, который был бы явным по умолчанию, за исключением некоторых обозначенных классов.
Точнее, у меня есть относительно простой шаблон класса, экземпляры которого должны быть преобразованы в какой-то другой тип (int
по всему этому вопросу, для простоты). Тем не менее, я хочу, чтобы это преобразование было явным по умолчанию, но все же позволяло, чтобы оно было неявным для одного другого класса, а именно для класса, передаваемого в качестве аргумента шаблона. Без этой последней части это будет выглядеть так:
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() const {
return i;
}
private:
int i;
};
Теперь я хочу написать что-то вроде A a(2); int i = a;
внутри методов T
(который должен быть классом).
Моя первая идея состояла в том, чтобы использовать объявления друзей и объявить частную перегрузку оператора преобразования. Однако перегрузка, основанная исключительно на explicit
, не допускается. Поэтому я попытался использовать const
вместо этого, и это сработало:
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() { // Public non-const
return i;
}
private:
int i;
operator int() const { // Private const
return i;
}
friend T;
};
... пока это не так. Это работает только при использовании неконстантных A
с, и хотя я не планирую использовать const A
с, я все же хотел бы, чтобы оно работало во всех случаях. Обратите внимание, что если общая перегрузка const
, а частная перегрузка - нет, это работает только с использованием const A
s.
Вот демонстрационная версия , показывающая, в каких случаях она работает или нет.
Я думал об использовании volatile
( demo ), и хотя это делает его лучше, оно все равно приводит к той же проблеме: оно работает только при использовании энергонезависимых A
s.
Есть ли лучший способ сделать это? В более общем смысле, есть ли способ решить проблему в самом первом предложении?