我的问题类似于When a compiler can infer a template parameter?,但有点复杂。
我想创建一个工厂函数,它会推断出其结果的类型,这样我就不必自己编写,而是使用auto(如下面的auto b = ...
或auto b3 = ...
)
我可以使用普通指针来处理代码,但是当我将它们更改为unique_ptr
时,编译器会抱怨。
以下是示例代码。
#include <iostream>
#include <memory>
template <typename T>
struct A {
T fA() const { return T(); }
};
struct Aint : A<int> {};
template <typename T>
struct B {
B(std::unique_ptr<A<T>> ptr) : ptr_(std::move(ptr)) {}
B(A<T>* ptr) : ptr_(ptr) {}
std::unique_ptr<A<T>> ptr_;
};
template <typename T>
std::unique_ptr<B<T>> CreateB(A<T>* a) {
return std::unique_ptr<B<T>>(new B<T>(a));
}
template <typename T>
std::unique_ptr<B<T>> CreateBFromUnique(std::unique_ptr<A<T>> a) {
return std::unique_ptr<B<T>>(new B<T>(std::move(a)));
}
int main() {
auto b = CreateB(new Aint);
std::cout << b->ptr_->fA() << "\n";
std::unique_ptr<Aint> a(new Aint);
// call below fails to compile
auto b2 = CreateBFromUnique(std::move(a));
// This works fine.
auto b3 = CreateBFromUnique<int>(std::move(a));
}
这里是clangs输出(g ++打印类似的消息):
templates1.cpp:34:15: error: no matching function for call to 'CreateBFromUnique'
auto b2 = CreateBFromUnique(std::move(a));
^~~~~~~~~~~~~~~~~
templates1.cpp:24:23: note: candidate template ignored: could not match 'A<type-parameter-0-0>' against 'Aint'
std::unique_ptr<B<T>> CreateBFromUnique(std::unique_ptr<A<T>> a) {
^
如何创建在此编译的工厂函数?
PS元请求:描述这个问题的规范方法是什么,以便轻松谷歌?
答案 0 :(得分:0)
当然,有不止一种方法可以做到,但是......
#include <memory>
template <typename T> T AtypeHelper(A<T>*){}
template <typename T>
using Atype = decltype(AtypeHelper((T*)0));
template <typename U, typename T = Atype<U>>
std::unique_ptr<B<T>> CreateBFromUnique(std::unique_ptr<U> a) {
return MakeUnique<B<T>>(std::move(a));
}
int main() {
auto b = CreateBFromUnique(MakeUnique<Aint>());
}
...您也可以考虑从typedef
导出A<T>
,以使T
可以轻松提取为typename U::value_type
。