如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )

How to use derived type in specialisation of return-type function template? ("couldn't infer template argument")

本文关键字:couldn argument template infer 类型 函数模板 返回类型 专用 派生      更新时间:2023-10-16

我有一个模板类和一个模板返回类型为的函数

template<typename T>
class Wrapper {
public:
Wrapper(const T& _data) : data(_data) { }
const T& get_data() {return data;};
private:
T data;
};
template <typename T>
Wrapper<T> build_wrapped(){
T t{};
return Wrapper<T>(t);
}

假设我想为一个特定的类型T扩展返回的Wrapper,并为该类型专门化build_wrapped()函数。因此,让我们创建一个模板来保存返回类型,并在build_wrapped():中使用它

template<typename T>
struct ReturnType {
using type = Wrapper<T>;
};
template <typename T>
typename ReturnType<T>::type build_wrapped(){
T t{};
return typename ReturnType<T>::type(t);
}

并使用它来提供专业化:

struct Foo{};
class ExtendedWrapper : public Wrapper<Foo> {
public:
ExtendedWrapper(const Foo& _data) : Wrapper(_data) {}
int get_answer() {return 42;};
};
template<>
struct ReturnType<Foo> {
using type = ExtendedWrapper;
};
template<>
typename ReturnType<Foo>::type build_wrapped(){
Foo t{};
return typename ReturnType<Foo>::type(t);
}

然而,gcc和clang都拒绝了最终声明。例如,clang返回:

错误:没有与函数模板专业化匹配的函数模板"build_wrapped">

注意:已忽略候选模板:无法推断模板参数"t">

我可以通过为Foo创建Wrapper的显式专业化来绕过使用ReturnType。然而,当我只想添加一些新功能(如ExtendedWrapper)时,这需要复制Wrapper中的所有代码(在我的实际生活中,这是一个实质性的类)。那么,这能做到吗?上面的方法有什么问题?

编译器已经告诉你问题是什么:

注意:忽略了候选模板:无法推断模板参数"t">

您需要显式指定模板参数。

template <>
typename ReturnType<Foo>::type build_wrapped<Foo>()
{ //                                        ^~~~~
Foo t{};
return typename ReturnType<Foo>::type(t);
}
相关文章: