C++ 用模板专门化模板
我有一个(免费)函数模板,看起来像这样C++ 用模板专门化模板,c++,templates,specialization,C++,Templates,Specialization,我有一个(免费)函数模板,看起来像这样 template <typename T> T get(); 模板 T get(); 现在我想为一个类专门化这个函数,这个类本身就是一个模板。但是我的编译器不想编译它,我现在想问的是这是否可能,以及我如何实现它。为了实现这个想法,代码可以如下所示:(不编译) 模板 模板 foo_类型get() 您所做的工作称为函数模板的部分专门化。但不允许函数模板的部分专门化。允许重载函数模板,但在这种情况下,也不可能重载,因为函数只有返回类型,并且不允许
template <typename T>
T get();
模板
T get();
现在我想为一个类专门化这个函数,这个类本身就是一个模板。但是我的编译器不想编译它,我现在想问的是这是否可能,以及我如何实现它。为了实现这个想法,代码可以如下所示:(不编译)
模板
模板
foo_类型get()
您所做的工作称为函数模板的部分专门化。但不允许函数模板的部分专门化。允许重载函数模板,但在这种情况下,也不可能重载,因为函数只有返回类型,并且不允许重载返回类型
因此,解决方案是:
namespace details
{
template <typename T>
struct worker
{
static T get();
};
template <typename T> //partial specialization of class is allowed
struct worker<foo<T>>
{
static foo<T> get();
};
}
template <typename T>
T get()
{
return details::worker<T>::get();
}
名称空间详细信息
{
模板
结构工人
{
静态T get();
};
模板//允许类的部分专门化
结构工人
{
静态foo-get();
};
}
模板
不明白
{
返回详细信息::worker::get();
}
如果您将重载定义为接受一个参数以使重载有效,也可以使用重载:
namespace details
{
template <typename T>
static T get(T*);
template <typename T>
static foo<T> get(foo<T>*); //now the overload is valid
}
template <typename T>
T get()
{
return details::get<T>(static_cast<T*>(0));
}
名称空间详细信息
{
模板
静态T-get(T*);
模板
静态foo-get(foo*);//现在重载有效
}
模板
不明白
{
返回详细信息::get(static_cast(0));
}
请注意,参数
static\u cast(0)
用于帮助编译器选择正确的重载。如果T
不是foo
,则将选择第一个重载,因为传递给它的参数类型将是T*
,而不是foo*
。如果T
是foo
,那么编译器将选择第二个重载,因为它更专业,在这种情况下可以接受传递给它的参数foo*
。正如纳瓦兹所说,标准不允许您这样做。但是,您可以将实现提取到类的静态方法中,并部分地专门化该类
template<class T>
struct get_impl{
static T get(){ ... }
};
template<class T>
struct get_impl<foo_type<T> >{
static foo_type<T> get(){ ... }
};
template<class T>
T get(){ return get_impl<T>::get(); }
模板
结构get\u impl{
静态T get(){…}
};
模板
结构get\u impl{
静态foo_类型get(){…}
};
模板
T get(){return get_impl::get();}
现在,看到解决方案,这是显而易见的。非常感谢。但现在我得到一个链接器错误。。有什么想法吗?@Xeo:哦。对你说得对。当我发布它的时候,我觉得我做错了什么,但我无法理解。@cooky:你把模板函数体放在了.cpp中了吗?:)不,链接错误是在重载函数时出现的。有点可笑,别问我编译器在那里做了什么。(不是很明显,他只是把他的任务委托给了链接者;)--不过,这现在行得通了,谢谢你们,现在我必须决定接受什么作为答案。也许我可以掷骰子静态_强制转换(nullptr)
template<class T>
struct get_impl{
static T get(){ ... }
};
template<class T>
struct get_impl<foo_type<T> >{
static foo_type<T> get(){ ... }
};
template<class T>
T get(){ return get_impl<T>::get(); }