我有这个方法
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':无法匹配函数定义现有的声明
第一个问题是你在这里缺少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& > ) { ???; }
请注意,返回对已分配指针的引用听起来确实是个坏主意。
您尝试的是重载,而不是专门化。由于function不能部分特化,我建议使用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>{}();
}