从模板参数的子类中推断出函数模板参数

时间:2015-09-23 01:05:50

标签: c++ templates

我的问题类似于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元请求:描述这个问题的规范方法是什么,以便轻松谷歌?

1 个答案:

答案 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