[basic.def.odr]/3:
A variable x
whose name appears as a potentially-evaluated expression
ex
is odr-used by ex
unless applying the lvalue-to-rvalue conversion
(4.1) to x
yields a constant expression (5.19) [..]
Unfortunately, applying the l-t-r conversion to v
at this point would not yield a constant expression - [expr.const]/2:
A conditional-expression e
is a core constant expression unless
the evaluation of e
, following the rules of the abstract machine
(1.9), would evaluate one of the following expressions: [..]
— an
lvalue-to-rvalue conversion (4.1) unless it is applied to
a non-volatile glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding
initialization, initialized with a constant expression [..], or
a non-volatile glvalue that refers to a non-volatile object defined with constexpr
, or that refers
to a non-mutable sub-object of such an object, or
- a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of
e
;
However, though the implementation suggested by Matt isn't correct, the idea certainly is. A simple way of using this approach is demonstrated in this answer, using a helper template. In your case, try
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{}; }
};
Demo.