C++11 variadic template beginner's problems

Started by
3 comments, last by TheUnbeliever 12 years, 2 months ago
[source]#include <iostream>

template <typename T>
T add(const T& a)
{ return a; }

template <typename T0, typename ... Ts>
auto add(const T0& a, const Ts& ... bs) -> decltype(a + add(bs ...))
{ return a + add(bs ...); }

int main()
{
std::cout << add(1, 2, 3) << "\n";
}[/source]

test.cpp: In function ‘int main()’:
test.cpp:13:29: error: no matching function for call to ‘add(int, int, int)’
test.cpp:13:29: note: candidates are:
test.cpp:4:3: note: template<class T> T add(const T&)
test.cpp:8:6: note: template<class T0, class ... Ts> decltype ((a + add(add::bs ...))) add(const T0&, const Ts& ...)

Works fine for add(1, 2). What's my mistake? I realize it's probably fairly fundamental. Thanks. :-)
[TheUnbeliever]
Advertisement
Using a decent compiler will help you, by producing readable errors:

clang++ -Wall -Werror -std=c++0x -c -I/Users/Shared/Projects/boost_1_48_0 -I. -I./Shared -c test.cpp -o build/test.o
test.cpp:17:22: error: no matching function for call to 'add'
std::cout << add(1, 2, 3) << "\n";
^~~
test.cpp:4:3: note: candidate function template not viable: requires 1 argument, but 3 were provided
T add(const T& a)
^
test.cpp:10:6: note: candidate template ignored: substitution failure [with T0 = int, Ts = <int, int="">]
auto add(const T0& a, const Ts& ... bs) -> decltype(a + add(bs ...))
^
1 error generated.
make: *** [build/test.o] Error 1

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Not the first time I've seen better error messages from Clang, and I do mean to give it a spin. All the same, they don't tell me anything I couldn't already fathom. Obviously the template substitution fails, I just don't know why. In my mind, it should instantiate the second template with <int, <int, int>> and then <int, <int>> and then finally the first template with <int>.
[TheUnbeliever]
decltype, remove it. be happy.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

You mean something like this?

[font=courier new,courier,monospace]template <typename T0, typename ... Ts>[/font]
[font=courier new,courier,monospace]T0 add(const T0& a, const Ts& ... bs)[/font]
[font=courier new,courier,monospace]{ return a + add(bs ...); }[/font]

That works, thanks. But I'd still like to know why the version with decltype doesn't work. Is it because the type of add<int, <int, int>> then depends on the type of add<int, <int>> which has not yet been instantiated?
[TheUnbeliever]

This topic is closed to new replies.

Advertisement