2015-09-23 103 views
1

我的问题类似于When a compiler can infer a template parameter?,但稍微复杂一点。从模板参数的子类中推断函数模板参数

我想创建一个工厂函数,这样我就不用写自己这推断其结果的类型,但使用自动代替(如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

有这样做的,当然不止一种方法,但是......

#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>()); 
} 

...你也可以考虑从A<T>导出typedef使T容易提取,就像这样typename U::value_type

相关问题