C++ 调用具有不同签名的函数,具体取决于类型
C++ Calling functions with different signatures, depending on type
我想知道以下场景的良好设计模式是什么。三问:
1) 我有一个模板 "Container" class 用于 "Derived" 的子class。我希望能够在一个向量中存储不同种类的模板对象(类型 A 或 B,都是 Derived 的 subclasses)。如何做到这一点?
2) 我有一个特定于模板的函数 "func",它在 Container 上运行并且具有可变数量的参数,具体取决于 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) 您可以将指向 A
的指针(类型 A *
)或指向 B
的指针(类型 B *
)存储在 std::vector<Derived *>
中,因为Derived
是 A
和 B
的基础。不能把一个Container<A>
和一个Container<B>
存到同一个vector中,因为它们之间没有继承关系。这也是(间接)将 foo
和 bar
转换为 unique_ptr<Container<Derived *> >
被编译器拒绝的原因。
2) 你的 func() 不是 "template specific function"。它甚至不是模板函数。它是一个重载函数,一种变体接受两个参数,另一种变体接受三个参数。
3) 鉴于您的代码无效,无法推断您的用例是什么。鉴于您正在尝试将对象转换为不相关的类型,我的猜测是您的用例在 C++ 中没有意义,更不用说为其使用模板了。
此外,不要在 C++ 中使用 Java(或您正在考虑的任何其他语言)技术,因为它们的工作方式不同。具体来说;
Container<A> * foo = new Container<A>(A(1));
Container<B> * bar = new Container<B>(B(true));
func(*foo,1,2);
func(*bar,false);
不需要。由于各种原因在 Java 中使用它在 C++ 中无效,即使代码可以编译。相反,这样做;
Container<A> foo A(1);
Container<B> bar B(true);
func(foo,1,2);
func(bar,false);
这是有效且安全的 C++(在 Java 中不起作用,但那是另一回事了)。
我想知道以下场景的良好设计模式是什么。三问:
1) 我有一个模板 "Container" class 用于 "Derived" 的子class。我希望能够在一个向量中存储不同种类的模板对象(类型 A 或 B,都是 Derived 的 subclasses)。如何做到这一点?
2) 我有一个特定于模板的函数 "func",它在 Container 上运行并且具有可变数量的参数,具体取决于 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) 您可以将指向 A
的指针(类型 A *
)或指向 B
的指针(类型 B *
)存储在 std::vector<Derived *>
中,因为Derived
是 A
和 B
的基础。不能把一个Container<A>
和一个Container<B>
存到同一个vector中,因为它们之间没有继承关系。这也是(间接)将 foo
和 bar
转换为 unique_ptr<Container<Derived *> >
被编译器拒绝的原因。
2) 你的 func() 不是 "template specific function"。它甚至不是模板函数。它是一个重载函数,一种变体接受两个参数,另一种变体接受三个参数。
3) 鉴于您的代码无效,无法推断您的用例是什么。鉴于您正在尝试将对象转换为不相关的类型,我的猜测是您的用例在 C++ 中没有意义,更不用说为其使用模板了。
此外,不要在 C++ 中使用 Java(或您正在考虑的任何其他语言)技术,因为它们的工作方式不同。具体来说;
Container<A> * foo = new Container<A>(A(1));
Container<B> * bar = new Container<B>(B(true));
func(*foo,1,2);
func(*bar,false);
不需要。由于各种原因在 Java 中使用它在 C++ 中无效,即使代码可以编译。相反,这样做;
Container<A> foo A(1);
Container<B> bar B(true);
func(foo,1,2);
func(bar,false);
这是有效且安全的 C++(在 Java 中不起作用,但那是另一回事了)。