从构造函数中的成员变量中减去模板参数

时间:2015-06-08 11:27:45

标签: c++ templates c++11

我有一个C ++库,它是C库的包装器。工厂类Creator创建的对象各自代表C库功能的一部分。 这些类构造函数是私有的,以确保所有对象都是通过Creator类创建的,因为C库需要一些内部魔法(我在下面的简化示例中省略了它)。

一切正常,但我有以下问题":

在课程UsesAandB中,我必须指定A<>两次的模板参数: 一旦进入成员声明(std::shared_ptr<A<int>>),一次进入构造函数的初始化列表(creator->createA<int>)。

由于我已经知道成员aInt的类型为std::shared_ptr<A<int>>,因此如何使用此知识在构造函数中调用相应的createA<int>()方法而不重复int或者如何完全避免拨打createA<int>()

#include <memory>

class Creator;

template<typename T>
class A
{
    friend class Creator;
private:
    A(int param) {}
    T value;
};

class B
{
    friend class Creator;
private:
    B(){}
};

class Creator
{
public:
    template<typename T>
    std::shared_ptr<A<T>> createA(int param) { return std::shared_ptr<A<T>>(new A<T>(param)); }
    std::shared_ptr<B> createB() { return std::shared_ptr<B>(new B());}
};

class UsesAandB
{
public:
    UsesAandB(std::shared_ptr<Creator> creator)
        : creator(creator),
          aInt(creator->createA<int>(0)),
          aDouble(creator->createA<double>(1)),
          b(creator->createB())
   {

   }
private:
    std::shared_ptr<Creator> creator;
    std::shared_ptr<A<int>> aInt;
    std::shared_ptr<A<double>> aDouble;
    std::shared_ptr<B> b;
};

int main()
{
    auto creator = std::make_shared<Creator>();
    UsesAandB u(creator);
    return 0;
}

3 个答案:

答案 0 :(得分:3)

要从shared_ptr获取类型,您需要将其传递给像这样的模板函数:

template <typename U>
shared_ptr< A<U> > CreateA( std::shared_ptr<Creator>& c,
                            const shared_ptr< A<U> >& p,
                            const U& val )
{
    return c->createA<U>(val);
}

然后简单地说:

aInt(CreateA(creator, aInt, 0 )),

此处示例 - http://ideone.com/Np7f8t

答案 1 :(得分:1)

我的想法,不知道它是否解决了任何问题,但你确实消除了在声明和构造函数调用中使用不同类型的机会。

template<typename T>
class A
{
    friend class Creator;
private:
    typedef T type;
    A(int param) {}
    T value;
};

class UsesAandB
{
typedef std::shared_ptr<A<int>> sharedA;

public:
    UsesAandB(std::shared_ptr<Creator> creator)
        : creator(creator),
          aInt(creator->createA<sharedA::element_type::type>(0)),
          aDouble(creator->createA<double>(1)),
          b(creator->createB())
   {

   }

private:
    std::shared_ptr<Creator> creator;
    sharedA aInt;
    std::shared_ptr<A<double>> aDouble;
    std::shared_ptr<B> b;
};

答案 2 :(得分:1)

您可以添加以下静态模板功能

UsesAandB(std::shared_ptr<Creator> creator)
        : creator(creator),
          aInt(create1((creator, aInt, 0)),
          aDouble(create1(creator, aDouble, 1)),
          b(creator->createB())
   {

   }

然后像这样初始化:

#pragma omp parallel{...}

create1要求共享指针仅推导出正确的类型。 问题是这段代码应该引发警告(这在nitializer列表中使用)