1

recently i was testing some c++ template codes and i found one mind-boggling error. According to my research on internet in particular stackoverflow, this code is completely valid however, compiler raises compile time error. Error is located below of code.

Code:

template<template<class> class C, typename T> void print(C<T>& c) {
}

int test() {
    vector<string> v(5, "Yow!");
    print(v);
    return 0;
}

Compiler Output:

In function ‘int test()’:
error: no matching function for call to ‘print2(std::vector<std::basic_string<char> >&)’
note: candidate is:
note: template<template<class> class C, class T> void print2(C<T>&)

It seems something is wrong about definition or my compiler but i tested this code with both g++ and clang++ in order to be sure about there is not any compiler dependent problem. Both of them raises same error.

I really appreciate any meaningful comments which aim to make clarification for this problem.

Thank you

Validus Oculus
  • 2,756
  • 1
  • 25
  • 34
  • Is there a specific reason to use template template function? Why not just like `template `? – fasked Dec 31 '13 at 06:25
  • I was trying some template examples and this example in book is shown as a valid code. But in my experiment it causes problem so i want to learn why this things happen. – Validus Oculus Dec 31 '13 at 06:28

2 Answers2

3

std::vector, the type being passed in as C, has more than one template parameter. It has the usual element type, but also an allocator. The easiest way to get around this while keeping a list of type arguments is to use a variadic template:

template<template<class...> class C, typename... Ts> void print(C<Ts...>& c)
                  ^^^^^^^^                   ^^^^^^             ^^^^^^^^

Actually using the individual type arguments is easier done, in most cases, by explicitly specifying them, as in Cheers' answer. If you don't care about the type arguments, feel free to not keep track of them. In the case of a container, you can even get them from just the container type:

template<typename Container> void print(Container& c) {
    typename Container::value_type t;
}
chris
  • 60,560
  • 13
  • 143
  • 205
2

Expanding on chris' answer, the following compiles fine with both visual c++ 12.0 and g++ 4.7.2:

#include <vector>
#include <string>
using namespace std;

template<template<class, class> class C, class T, class U> void print(C<T, U>& c)
{ (void) c; }

void test() {
    vector<string> v(5, "Yow!");
    print(v);
}

However, if you really just want to output the items of a container, why not do this instead:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

template< class C >
void print( C const& c )
{
    for( auto const& item : c )
    {
        cout << item << endl;
    }
}

auto main() -> int
{
    vector<string> v(5, "Yow!");
    print(v);
}
Community
  • 1
  • 1
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • if you look my question, it is not "how can i print value of container". I wonder about why this thing happens, what is wrong with this example because in book it is valid sample and i thought something is wrong with my compiler or compiler parameters. – Validus Oculus Dec 31 '13 at 06:50
  • can you test my example in your compiler ? – Validus Oculus Dec 31 '13 at 06:56
  • 2
    @MuratKarakuş: i already tested the example, first thing. it should not compile cleanly with any modern C++ compiler since the `print` function is non-`void` yet returns by executing to the end with no return value specified. which book is this? – Cheers and hth. - Alf Dec 31 '13 at 07:49
  • oh, I meant `test` function, sorry. – Cheers and hth. - Alf Dec 31 '13 at 08:17
  • you are right "it should not compile successfully but it does". http://stackoverflow.com/questions/9936011/if-a-function-returns-no-value-with-a-valid-return-type-is-it-okay-to-for-the you should look here why is it compiles and runs successfully. Anyway i should return something .. – Validus Oculus Jan 01 '14 at 13:05
  • @MuratKarakuş: I did not write what you quote. there is a big difference between "compile cleanly" and "compile successfully". also, can you please tell (I already asked), which book and compiler is this? – Cheers and hth. - Alf Jan 01 '14 at 19:53
  • hm, apparently he doesn't maintain an errata list (while there is at least one errata list for the book at unrelated site). and as i recall from years ago it's no good to report a bug. :( however, one might try anyway. – Cheers and hth. - Alf Jan 03 '14 at 04:26
  • There is no doubt about bruce eckel deep knowledge, maybe he published errata list and i am using old edition book. Anyway, thanks a lot for your contribution. – Validus Oculus Jan 03 '14 at 04:45
  • @MuratKarakuş: the best books have errata lists. e.g. bjarne's books have errate lists (proving that even the best commit errors). but bruce's book is *free*. – Cheers and hth. - Alf Jan 03 '14 at 04:59