2015-09-23 101 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

相關問題