C ++根据类型调用具有不同签名的函数

时间:2015-04-14 08:23:20

标签: c++ templates polymorphism

我想知道以下场景的优秀设计模式是什么。三个问题:

1)我有一个模板化的“Container”类,用于“Derived”的子类。我希望能够在向量中存储不同类型的模板对象(类型A或B,都是Derived的子类)。怎么做?

2)我有一个特定于模板的函数“func”,它对Containers进行操作,并且具有可变数量的参数,具体取决于Container的模板类型是A还是B.在运行时检查模板类型的好方法是什么调用适当的函数?

3)模板甚至对这个用例有意义吗?

#include <iostream>
#include <string>
#include <vector>
#include <memory>

using namespace std;

struct Derived {};

struct A : Derived { 
    int x; 
    A(int x) : x(x) {}
};
struct B : Derived { 
    bool y; 
    B(bool y) : y(y) {}
};

template <typename T>
struct Container
{
    T item;
    Container(T i) : item(i) {}
};

// definition of a template function for type a, with specialization
void func(Container<A> c, int a, int b) {
    cout << "update for A called" << endl;
}

void func(Container<B> c, bool x) {
    cout << "update for B called" << endl;
}

int main(int argc, char const *argv[])
{
    Container<A> * foo = new Container<A>(A(1));
    Container<B> * bar = new Container<B>(B(true));
    // test that func() works
    func(*foo,1,2);
    func(*bar,false);

    vector< Container<Derived>* > vec;

    // this does not work
    vec.push_back(unique_ptr< Container<Derived *> >(foo));
    vec.push_back(unique_ptr< Container<Derived *> >(bar));

    for (Container<Derived>* d : vec) {
        // how to call the proper func(d)?
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

1)您可以在A中存储指向A *(类型B)或指向B *(类型std::vector<Derived *>)的指针,因为{{ 1}}是DerivedA的基础。无法将BContainer<A>存储到同一向量中,因为它们之间没有继承关系。这也是(间接)导致您的编译器拒绝将Container<B>foo转换为bar的原因。

2)你的func()不是&#34;模板特定功能&#34;。它甚至不是模板化的功能。它是一个重载的函数,一个变量接受两个参数,一个变量接受三个。

3)鉴于您的代码无效,无法推断您的用例是什么。鉴于您正在尝试将对象转换为不相关的类型,我的猜测是您的用例在C ++中没有意义,更不用说使用模板了。

此外,不要在C ++中使用Java(或您正在考虑的任何其他语言)技术,因为它们的工作方式不同。具体而言;

unique_ptr<Container<Derived *> >

是不必要的。它在Java中用于各种原因,即使代码编译,它们在C ++中也是无效的。相反,这样做;

Container<A> * foo = new Container<A>(A(1));
Container<B> * bar = new Container<B>(B(true));
func(*foo,1,2);
func(*bar,false);

这是有效且安全的C ++(并且不适用于Java,但这是另一个故事)。