使用数组<>在通用功能中

时间:2013-07-16 18:15:28

标签: generics c++-cli

在我的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

为什么不编译?我想做什么的替代方案是什么?

2 个答案:

答案 0 :(得分:2)

无法编译的原因是没有print<T>函数。唯一的print函数适用于intString

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