简体   繁体   English

从构造函数中的成员变量推导模板参数

[英]Deduce template parameter from member variable in constructor

I have a C++ library which is a wrapper for a C library. 我有一个C ++库,它是C库的包装器。 A factory class Creator creates objects of which each represents parts of the functionality of the C library. 工厂类Creator创建对象,每个对象代表C库功能的一部分。 These class constructors are private to ensure that all objects are created through that Creator class because the C library requires some internal magic (which I omitted in the following, simplified example). 这些类构造函数是私有的,以确保通过该Creator类创建所有对象,因为C库需要一些内部魔术(在下面的简化示例中,我省略了)。

It all works, but I have the following "problem": 一切正常,但是我有以下“问题”:

In class UsesAandB I have to specify the template parameter of A<> twice: Once in the member declaration ( std::shared_ptr<A<int>> ) and once in the initialization list of the constructor ( creator->createA<int> ). UsesAandB类中,我必须两次指定A<>的模板参数:一次在成员声明( std::shared_ptr<A<int>> creator->createA<int> )中,一次在构造函数的初始化列表中( creator->createA<int> )。

Since I already know that member aInt will be of type std::shared_ptr<A<int>> , how can I use this knowledge to call the corresponding createA<int>() method in the constructor without repeating int or how can I avoid the call to createA<int>() at all? 由于我已经知道成员aInt的类型将为std::shared_ptr<A<int>> createA<int>() ,因此如何在不重复int情况下如何使用此知识在构造函数中调用相应的createA<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;
}

To get the type from the shared_ptr , you need to pass it to a template function like this one: 要从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);
}

Then simply: 然后简单地:

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

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

My idea, don't know if it solves anything, but you do eliminate the chance of having different types in the declaration and constructor call. 我的想法是,不知道它是否可以解决任何问题,但是您确实消除了在声明和构造函数调用中使用不同类型的机会。

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;
};

You could add the following static template function 您可以添加以下静态模板功能

template <class T>
static std::shared_ptr<T> create1(std::shared_ptr<Creator> &creator, std::shared_ptr<T> &,T value)
{
   return creator->createA(value) ;
}

An then initialize like this: 然后像这样初始化:

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

   }

create1 requires the shared pointer only to deduce the right type. create1仅需要共享指针即可推断出正确的类型。 A problem is that this code should raise a warning (this used in nitializer list) 问题在于此代码应发出警告(在硝化剂列表中使用)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM