C ++模板方法专门化返回指针或引用

时间:2016-10-24 18:01:25

标签: c++ c++11 templates

我有这个方法

template <typename T>
T GetFnInput(){
  //.... here is obtained void * t value from some library
  return (T)(t);
}

我有几种不同类型的模板专业化

template <>
uint32 GetFnInput<uint32>(){
    return 0;
}

template <>
bool GetFnInput<bool>(){
    return true;
}

但是,我需要专业化参考。我试过这个(代码很乱,不应该在生产中使用,这只是为了我的测试目的):

template <typename T, 
typename BaseT = std::decay<T>::type,
typename std::enable_if <std::is_reference<T>::value == true>::type* = nullptr >
T GetFnInput(){
  BaseT * t = new BaseT();
  return *t;
}

另外,我已将typename std::enable_if <std::is_reference<T>::value == false>::type* = nullptr >添加到原始版本(上方)GetFnInput() 但它不会编译,以错误结束:

  

错误C2244:'GetFnInput':无法将函数定义与a匹配   现有声明

2 个答案:

答案 0 :(得分:3)

第一个问题是你在这里缺少typename

typename BaseT = std::decay<T>::type,
                ^^^

一旦你有了这个问题,你就会遇到第二个问题,即原始功能模板GetFnInput<int&>()和这个新功能模板GetFnInput<typename>之间的GetFnInput<typename, typename, typename>调用不明确。这两个函数模板彼此重载,否则无关。

通常希望你想做的是将模板参数提升到参数列表中,以便更容易过载:

template <class T> struct tag { using type = T; };

template <class T>
auto get() -> decltype(get_impl(tag<T>{}))
{
    return get_impl(tag<T>{});
}

然后您可以更轻松地编写get_impl函数模板。具体类型只是特定的重载:

uint32_t get_impl(tag<uint32_t> ) { return 0; }

参考类型只是一个模板:

template <class T>
T& get_impl(tag<T& > ) { ???; }

请注意,返回对已分配指针的引用听起来真的很糟糕。

答案 1 :(得分:2)

你尝试过载,而不是专业化。 由于函数不能部分专门化,我建议使用struct代替:

template <typename T>
struct helper
{
    T operator() const { return {}; }
};

template <>
struct helper<bool>
{
    bool operator() const { return true; }
};

template <typename T>
struct helper<T&>
{
    T& operator() const { static T t; return t; }
};

template <typename T>
T GetFnInput(){
    return helper<T>{}();
}