When using std::enable_if
along with a templatized struct it leads to ambiguous partial specialization for const int*
In the example below, the compiler complains if the std::enable_if
is used while there is no issue in compilation when the commented lines are uncommented and std::enable_if
is not used.
#include <type_traits>
template <typename , typename P = void> struct pType;
template<typename t, typename d, typename config>
struct BP;
template<typename t>
struct MP: std::false_type{};
template<typename t, typename d, typename config>
struct MP<BP<t,d,config>>: std::true_type{};
template <typename T> struct pType <const T *
,typename std::enable_if<!MP<T>::value>::type> {};
// >{};
template <typename T> struct pType <T *
,typename std::enable_if<!MP<T>::value>::type> {};
// >{};
template <typename T, typename P> struct pType {};
int main() {
pType<int*> a;
pType<const int*> b;
}
Why does the compiler not understand which version of the struct it has to pick? What would be the right way to implement this?
CodePudding user response:
const int*
can match const T*
with T=int, but it also matches T*
with T=const int.
So matches both versions.
CodePudding user response:
As you are using std::enable_if
already you can add another condition via std::is_const
:
#include <type_traits>
#include <iostream>
template <typename , typename P = void> struct pType;
template<typename t, typename d, typename config>
struct BP;
template<typename t>
struct MP: std::false_type{};
template<typename t, typename d, typename config>
struct MP<BP<t,d,config>>: std::true_type{};
template <typename T> struct pType <T *
,typename std::enable_if<!MP<T>::value && std::is_const_v<T>>::type> {
static const int a = 42;
};
// >{};
template <typename T> struct pType <T *
,typename std::enable_if<!MP<T>::value && !std::is_const_v<T>>::type> {
static const int a = 0;
};
// >{};
template <typename T, typename P> struct pType {};
int main() {
pType<int*> a;
pType<const int*> b;
std::cout << a.a;
std::cout << b.a;
}