Reputation: 11
I'm trying to 'overload' template function in class, depending on specialisation argument's parent template class. However, I get the following error.
error C2938: 'std::enable_if_t<false,bool>' : Failed to specialize alias template
What is wrong here?
#include <memory>
#include <type_traits>
template <template <typename...> class BaseTemplate, typename Derived, typename TCheck = void>
struct test_base_template;
template <template <typename...> class BaseTemplate, typename Derived>
using is_base_template_of = typename test_base_template<BaseTemplate, Derived>::is_base;
//Derive - is a class. Let inherit from Derive, so it can cast to its protected parents
template <template <typename...> class BaseTemplate, typename Derived>
struct test_base_template<BaseTemplate, Derived, std::enable_if_t<std::is_class_v<Derived>>> : Derived
{
template<typename...T>
static constexpr std::true_type test(BaseTemplate<T...>*);
static constexpr std::false_type test(...);
using is_base = decltype(test((test_base_template*) nullptr));
};
//Derive - is not a class, so it always false
template <template <typename...> class BaseTemplate, typename Derived>
struct test_base_template<BaseTemplate, Derived, std::enable_if_t<!std::is_class_v<Derived>>>
{
using is_base = std::false_type;
};
template<typename type>
class MyClass
{
public:
template <typename Dummy = type, typename std::enable_if_t<is_base_template_of<std::weak_ptr, type>::value, bool> = bool()>
std::shared_ptr<typename type::element_type> get()
{
return m_data.lock();
}
template <typename Dummy = type, typename std::enable_if_t<is_base_template_of<std::shared_ptr, type>::value, bool> = bool()>
std::shared_ptr<typename type::element_type> get()
{
return m_data;
}
private:
type m_data;
};
int main()
{
MyClass<std::weak_ptr<int>> t;
auto a1 = t.get();
MyClass<std::shared_ptr<int>> t2;
auto a2 = t2.get();
}
Readed this thread std::is_base_of for template classes
Upvotes: 1
Views: 121
Reputation: 1
Does that mean it is impossible to have one of theese functions at a time depending on m_data type?
You can use constexpr if
as shown below:
template<typename type>
class MyClass
{
public:
std::shared_ptr<typename type::element_type> get()
{
if constexpr(is_base_template_of<std::weak_ptr, type>::value)
{
return m_data.lock();
}
else if constexpr(is_base_template_of<std::shared_ptr, type>::value)
{
return m_data;
}
//make sure that this non-void returning function returns something if control reaches here
}
};
Upvotes: 0