我有这个方法
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匹配 现有声明
答案 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>{}();
}