Home > Net >  ambiguous partial specialization of const int * with std::enable_if in templated struct
ambiguous partial specialization of const int * with std::enable_if in templated struct

Time:03-08

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;
}
  • Related