简体   繁体   中英

How can I write a C++ function that returns different types of std::list based on processing?

What is wrong with below code at the indicated points? I want to return list of integers or characters or strings based on what program read somewhere in a file. I tried below code but it throws me error. I am a bit weak with templates as you can see.

template <class T> 
std::list<T> function1(int type)
{
   using namespace std;
   if (1 == type)
      return list<int>(3, 100); / No error
   else if (2 == type){
      list<wchar_t> temp;
      temp.push_back(L'a');  // C2664 error here
      return temp;
   }else if (3 == type){
      list<wstring> temp;
      temp.push_back(L"a"); // C2664 error here
      return temp;
   }else
      return nullptr;   // C2664 error here
}

I have pointed out the points where "visual studio 2013 community edition update 4" throws compiler error C2664. How can I write like this where I can get the list based on the processing inside? One of the error is below.

Error   1   error C2664: 'std::list<int,std::allocator<_Ty>>::list(std::initializer_list<_Ty>,const std::allocator<_Ty> &)' : cannot convert argument 1 from 'std::list<wchar_t,std::allocator<wchar_t>>' to 'const std::list<int,std::allocator<_Ty>> &'

That is not possible, templates need to be resolved during compile-time but the value of type is not known there. You would need to use some indirection such as boost::variant or non-templated interface. Or rather use a completely different approach.

In other words: the template itself does not contain enough information for it to be compiled. You need to instantiate a it by supplying the template arguments when you use the template; the compiler cannot decide to figure out its arguments later (or it would probably involve some just-in-time compilation). I don't think you can use specialization to work around this, because the return types would not be compatible. (Sorry that I wrote a new answer... I do not yet have the privilege to comment...)

It would be hard to decide the type of the objects in the list and then return it or a pointer to it so that you can use it in the function that called function1 . You can consider refactoring your code. If possible, you can try calling other functions that do further processing from within the function instead.

If you are adamant on returning the list from function1 : one idea that I can think of is to create a wrapper class that contains a void* pointer to the list (dynamically allocated), and something that tells you the type (say, int type ). But then other functions would probably have to follow this pattern. JK. (It would definitely create more trouble that it solves.)

For any instantiation of your function template on any particular type, at least one literal is likely to be incompatible with that type.

You can use specializations of some traits class that provides values of the various supported types. This makes it easy to support new types. Or you can just use overloads of the function for the various supported types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM