简体   繁体   中英

"Class template has already been defined" when making similar but different specializations

I have two class specializations. I want one of them to be used when T::A exists and the other to be used when T::B exists, which should be multually exclusive in practice. I am using std::void_t< decltype(... ) > to test for existence. I expect that expression to fail to evaluate for either one or the other specialization, and so I expect SFINAE to cause one of the specializations to be ignored.

template< typename T, typename Enable = void >
class C{};

template< typename T >
class C< T, std::void_t< decltype( T::A ) > > {};

template< typename T >
class C< T, std::void_t< decltype( T::B ) > > {};

However, MSVC just gives me

(On line containing T::B): error C2953: 'C<T,void>': class template has already been defined
(On line containing T::A): note: see declaration of 'C<T,void>'

What am I doing wrong?

Clang also rejects this code, but not GCC. This is not the first time I'm seeing problems with std::void_t .

I would stay away from it, and prefer decltype(void(T::A)) .

Or you can define your own robust void_t (code taken from cppreference ):

template<typename... Ts> struct make_void { typedef void type; };
template<typename... Ts> using void_t = typename make_void<Ts...>::type;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM