当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ cli - Using array<> in generic function

问题描述:

In my C++/CLI code, I have about 20 different classes. I have overloaded a print function 20 times to handle an instance of each class. Now I need to additionally support arrays of objects of each of those 20 classes and hate to have to write another 20 overloads which are mostly verbatim copies of each other. As an example, see below:

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;

}

But the above results in the following error:

error C2665: 'print' : none of the 2 overloads could convert all the argument types

Why doesn't this compile? What is the alternative for what I am trying to do?

网友答案:

The reason it doesn't compile is that generic methods, unlike template methods, exist for all types possible. Template methods are created just when they are called. Since you're only calling print with a string array, a template method definition would compile a version that explicitly takes a string array, and nothing else. It would be implemented to call the print(String^) method, and there'd be no errors.

Since it's generic, there's only one compiled version of the method. If you pass a T to another method, there has to be an overload of that method that can take any parameter, even ones you're not using in your program. For this method, if you're going to pass a T to a method, it has to take a parameter of type Object^.

To make this work, I'd implement print so that it takes an Object, and use reflection to find the class name to print.

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

If you want to provide specific versions for specific types, implement some additional logic in the print method:

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]);
}
网友答案:

The reason it can't be compiled is that there is no print<T> function. The only print functions are for int and String.

A C++ template will work:

template <class T>
void print(array<T> ^ts){
  for(int i = 0, n = ts->Length; i < n; ++i)
    print(ts[i]);
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: