我正在尝试在类中“重载”模板函数,具体取决于专业化参数的父模板类。但是,我收到以下错误。
错误 C2938:'std::enable_if_t
':无法专门化别名模板
这里出了什么问题?
#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();
}
阅读了此线程模板类的 std::is_base_of
这是否意味着根据 m_data 类型一次不可能拥有这些功能之一?
您可以使用
constexpr if
,如下所示:
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
}
};