Ответ 1
[basic.def.odr]/3:
Переменная
x
, имя которой отображается как потенциально оцененное выражениеex
является odr-используемымex
, если не применить преобразование lvalue-to-rvalue (4.1) доx
дает постоянное выражение (5.19) [..]
К сожалению, применение преобразования l-t-r в v
в этот момент не даст постоянного выражения - [expr.const]/2:
Условное выражение
e
является основным постоянным выражением, если только оценкаe
, следуя правилам абстрактной машины (1.9), оценил бы одно из следующих выражений: [..]- преобразование lvalue-to-rvalue (4.1), если оно не применяется к
нелетучий glvalue интегрального или перечисляемого типа , который ссылается на нелетучий объект const с предшествующим инициализация, инициализированная константным выражением [..] или
нестабильный glvalue , который ссылается на энергонезависимый объект, определенный с помощью
constexpr
, или который ссылается к не изменяемому под-объекту такого объекта, или- нелетучий glvalue литерального типа , который относится к энергонезависимому объекту, срок службы которого начинался с оценки
e
;
Однако, хотя реализация, предложенная Мэттом, неверна, идея, безусловно, такова. Простой способ использования этого подхода демонстрируется в этом ответе, используя шаблон-помощник. В вашем случае попробуйте
template <bool cond, int id=0>
using distinct_enable_if =
typename std::enable_if<cond, std::integral_constant<int,id>*>::type;
class test
{
public:
template< class... T,
distinct_enable_if<sizeof...(T) == 10> = nullptr>
test( T&&... ) {}
template< class T,
distinct_enable_if<std::is_arithmetic<T>{}> = nullptr>
operator T() const { return T{}; }
/* Note the additional template argument:
It ensures that the template parameter lists are not identical,
and the ODR isn't violated */
template< class T,
distinct_enable_if<std::is_pointer<T>{}, 1> = nullptr>
operator T() const { return T{}; }
};
Демо.