4

I'm not new to templates but I ran into a rather curious problem where I need to separate a template type into it's components for the data serializer I'm working on. It's hard to explain so I've demonstrated it.

Here's my simplified example problem, example.cpp.

template<typename T> void foo(T& arg) { }
template<typename T, typename V> void foo(T<V>& arg) { }

int main(int argc, char *argv[])
{
  foo(argc);
  return 0;
}

I get an error and then a warning which seems to indicate it's trying to instantiate both functions when only one of them is suitable.

$ g++ -Wall -W example.cpp 
example.cpp:2:43: error: ‘T’ is not a template
 template<typename T, typename V> void foo(T<V>& arg) { }
                                           ^
example.cpp: In instantiation of ‘void foo(T&) [with T = int]’:
example.cpp:6:11:   required from here
example.cpp:1:34: warning: unused parameter ‘arg’ [-Wunused-parameter]
 template<typename T> void foo(T& arg) { }
                                  ^~~

Any suggestions on how to resolve my problem and/or prevent this confusion?

Gravis
  • 992
  • 11
  • 17
  • 1
    in case no one else mentions it, thanks for posting the epitome of a *minimal* complete example that produces your problem. If you could have made it more minimal, I don't see how. Well presented. – WhozCraig Jul 08 '17 at 04:59

1 Answers1

6

Template template-parameters (parameters that are themselves deducible templates) require a different syntax that what you're using. As you've written it, the compiler does not expect T to be a template, so the syntax T<V> make no sense.

template< template<class> class T, class V> void foo(T<V>& arg>)

would be a correct example.

Example

#include <iostream>

template<typename T> void foo(T& arg)
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

template<template<class> class T, class V> void foo(T<V>& arg)
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
}


template<class T>
struct Bar
{

};

int main(int argc, char *argv[])
{
    foo(argc);

    Bar<int> bar;
    foo(bar);

    return 0;
}

Output

void foo(T &) [T = int]
void foo(T<V> &) [T = Bar, V = int]
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • Quick question: where is `__PRETTY_FUNCTION__` defined? – Francis Cugler Jul 08 '17 at 08:10
  • 1
    @FrancisCugler it's a gcc/clang thing. compiler-provided macros. – WhozCraig Jul 08 '17 at 08:11
  • ah okay I'm on windows; using MSVC so guess I'd have to stick with `__FUNCTION__` but it only gives just the name as in `foo` unless if there is one that is equivalent that I don't know of. – Francis Cugler Jul 08 '17 at 08:16
  • 1
    @FrancisCugler I *think* `__FUNCSIG__` may do what you want. I haven't really tried it, but according to [their documentation](https://msdn.microsoft.com/library/b0084kay.aspx), poor as it is for that specific macro. Best of luck. – WhozCraig Jul 08 '17 at 08:21
  • I had already known about `__FUNCTION__`. After doing a quick search I have found one similar to gcc/clang's `__PRETTY_FUNCTION__` and that is `__FUNCSIG__` and it's output looks like: `void __cdecl foo` & `void __cdecl foo(struct Bar &)` for the console output. – Francis Cugler Jul 08 '17 at 08:22
  • Well; I've used `__FUNCTION__` in the past with a custom made `ExceptionHandler` class, but when I seen the `__PRETTY_FUNCTION__`'s output I really liked what I saw. – Francis Cugler Jul 08 '17 at 08:24
  • 1
    @FrancisCugler it's *incredibly* handy for testing mysterious deductions. I wish MS had the identical feature, but you kinda have to dance with the one you brought. – WhozCraig Jul 08 '17 at 08:25
  • Yeah; that's Microsoft for you. If it wasn't so expensive I've might of purchased Intel's C++ compiler only because I do have an Intel Main Board and Processor, but to keep things affordable I'm working with MSVC 2013, 15, & 17. I use to have 05, 08, 10 & 12 but no longer use them and no longer installed. I keep 13 around for some of my older projects. – Francis Cugler Jul 08 '17 at 08:27
  • 1
    https://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func – Richard Hodges Jul 08 '17 at 08:30