0

I have this template to print out Collection structures but it seems like the function is precompiled with the argument???

If I only do the print statement inside the function, then the if else cases for the type does work, however, if I add different implementation for each case, it tests the argument against every case.

It gives an error before the program run (I think. I could not step through the code even though I put my break point to the start of the program).

Could someone give me a lecture on this please? and how to bypass this problem? Thank you. Appreciate it.

  template <typename T>
  void print(T& collection)
  {
     string type = typeid(T).name();

     if(type.find("map") != string::npos){
        for(auto const& item : collection){
           std::cout << item.first << " " << item.second << endl;
        }
     }
     else {
        for(auto const& item : collection){
           std::cout << item << std::endl;
        }
     }
  }

Here is the error if I call the function with a map:

 error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'const std::__1::pair<const std::__1::basic_string<char>, int>')
                    std::cout << item << std::endl;

Similarly, if called with an array:

 error: member reference base type 'const int' is not a structure or union
                    std::cout << item.first << " " << item.second << endl;
2
  • Here is the problem: though you print a key-value separately for a map collection during runtime, the code for second-for still needs to be compiled. and obviously, there is no overload for std::cout carring std::pair as its input. Commented Jul 14, 2015 at 4:19
  • never used this but it looks as it could contain some of the code you're looking for. Also you might wanna have a look here. Roughly said, templates are the static answer to the dynamic switch/if-type[name] approach and should be preferred as long as all the info they need is available at compile time. Commented Jul 14, 2015 at 7:14

2 Answers 2

1

Using run time check to execute different lines of code is problematic when the template parameter does not support the operations you want to perform.

What you need is something like:

template <typename T>
void print(T& collection)
{
   for ( auto const& item : collection )
   {
      std::cout << item << endl;
   }
}

To be able to use the above function with std::map, provide an operator<<() overload for std::pair.

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& out, std::pair<T1, T2> const& p)
{
   return out << p.first << " " << p.second;
}
Sign up to request clarification or add additional context in comments.

Comments

0

You can shorten the print function with the below simple macro.

#define dbg_cnt(cnt) copy(cnt.begin(), cnt.end(), ostream_iterator<decltype(cnt)>(cout, " ")

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.