在我的C ++ / CLI代码中,我有大约20个不同的类。我已经重载了print
函数20次来处理每个类的实例。现在我需要额外支持这20个类中每个类的对象数组,并且不得不编写另外20个重载,这些重载大多是彼此的逐字副本。例如,见下文:
void print(int i){
Console::WriteLine("Integer: {0}", i);
}
void print(String ^s){
Console::WriteLine(L"Hello " + s);
}
generic <typename T>
void print(array<T> ^ts){
for(int i = 0, n = ts->Length; i < n; ++i)
print(ts[i]);
}
int main(array<System::String ^> ^args)
{
array<String^> ^s = gcnew array<String^>{ L"apple", L"ball", L"car" };
print(s);
Console::WriteLine(L"Hello World");
return 0;
}
但上述结果导致以下错误:
error C2665: 'print' : none of the 2 overloads could convert all the argument types
为什么不编译?我想做什么的替代方案是什么?
答案 0 :(得分:2)
无法编译的原因是没有print<T>
函数。唯一的print
函数适用于int
和String
。
C ++模板将起作用:
template <class T>
void print(array<T> ^ts){
for(int i = 0, n = ts->Length; i < n; ++i)
print(ts[i]);
}
答案 1 :(得分:1)
它不编译的原因是,与模板方法不同,泛型方法可用于所有类型。模板方法在调用时就会创建。由于您只使用字符串数组调用print
,因此模板方法定义将编译显式获取字符串数组的版本,而不是其他任何内容。它将被实现为调用print(String^)
方法,并且没有错误。
由于它是通用的,因此该方法只有一个编译版本。如果您将T
传递给另一个方法,那么该方法可能需要重载任何参数,即使您在程序中未使用的参数也是如此。对于此方法,如果您要将T
传递给方法,则必须采用Object^
类型的参数。
为了完成这项工作,我实现print
以便它需要一个Object,并使用反射来查找要打印的类名。
void print(Object^ o)
{
Console::WriteLine("{0}: {1}", o->GetType()->Name, o);
}
generic <typename T>
void print(array<T> ^ts){
for(int i = 0, n = ts->Length; i < n; ++i)
print(ts[i]);
}
如果要为特定类型提供特定版本,请在print方法中实现一些额外的逻辑:
void print(Object^ o){
if(o->GetType() == String::typeid)
Console::WriteLine("Hello {0}", o);
else
Console::WriteLine("{0}: {1}", o->GetType()->Name, o);
}
generic <typename T>
void print(array<T> ^ts){
for(int i = 0, n = ts->Length; i < n; ++i)
print(ts[i]);
}