Thread C++ member function template variadic template - c++

I try to call a member function of an object using a thread.
If the function doesn't have a variadic template (Args ... args), no problem, it works:
Consider the two classes:
GeneticEngine
template <class T>
class GeneticEngine
{
template <typename ... Args>
T* run_while(bool (*f)(const T&),const int size_enf,Args& ... args)
{
std::thread(&GeneticThread<T>::func,islands[0],f,size_enf);
/* Some code */
return /* ... */
}
private:
GeneticThread<T>** islands;
}
GeneticThread
template <class T>
class GeneticThread
{
void func(bool (*f)(const T&),const int size_enf)
{
/* Some code */
};
}
With this, it's OK.
Now, I add a variadic template to the same functions:
GeneticEngine
template <class T>
class GeneticEngine
{
template <typename ... Args>
T* run_while(bool (*f)(const T&,Args& ...),const int size_enf,Args& ... args)
{
std::thread(&GeneticThread<T>::func,islands[0],f,size_enf,args ...);
/* Other code ... */
}
private:
GeneticThread<T>** islands;
}
GeneticThread
template <class T>
class GeneticThread
{
template <typename ... Args>
void func(bool (*f)(const T&,Args& ...), const int size_enf, Args& ... args)
{
/* Code ... */
};
}
With this code, GCC doesn't compile: (sorry for this error message)
g++ main.cpp GeneticEngine.hpp GeneticThread.hpp Individu.hpp GeneticThread.o -g -std=c++0x -o main.exe
In file included from main.cpp:2:0:
GeneticEngine.hpp: In instantiation of ‘T* GeneticEngine<T>::run_while(bool (*)(const T&, Args& ...), int, Args& ...) [with Args = {}; T = Individu]’:
main.cpp:24:78: required from here
GeneticEngine.hpp:20:13: erreur: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, GeneticThread<Individu>*&, bool (*&)(const Individu&), const int&)’
GeneticEngine.hpp:20:13: note: candidates are:
In file included from GeneticThread.hpp:14:0,
from GeneticEngine.hpp:4,
from main.cpp:2:
/usr/include/c++/4.7/thread:131:7: note: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
/usr/include/c++/4.7/thread:131:7: note: template argument deduction/substitution failed:
In file included from main.cpp:2:0:
GeneticEngine.hpp:20:13: note: couldn't deduce template parameter ‘_Callable’
In file included from GeneticThread.hpp:14:0,
from GeneticEngine.hpp:4,
from main.cpp:2:
/usr/include/c++/4.7/thread:126:5: note: std::thread::thread(std::thread&&)
/usr/include/c++/4.7/thread:126:5: note: candidate expects 1 argument, 4 provided
/usr/include/c++/4.7/thread:122:5: note: std::thread::thread()
/usr/include/c++/4.7/thread:122:5: note: candidate expects 0 arguments, 4 provided
I really do not understand why this difference makes this error. And I can not fix it.
In both the main.cpp is like that:
/* Individu is another class */
int pop_size = 1000;
int pop_child = pop_size*0.75;
GeneticEngine<Individu> engine(/*args to constructor*/);
bool (*stop)(const Individu&) = [](const Individu& best){
return false;
};
Individu* best = engine.run_while(stop,pop_child);
I use : «gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) »
I tried:
std::thread(&GeneticThread<T>::func<Args...>, islands[0], f, size_enf, args ...);
Now I have another error:
GeneticEngine.hpp: In member function ‘T* GeneticEngine<T>::run_while(bool (*)(const T&, Args& ...), int, Args& ...)’:
GeneticEngine.hpp:20:53: erreur: expansion pattern ‘((& GeneticThread<T>::func) < <expression error>)’ contains no argument packs
GeneticEngine.hpp:20:24: erreur: expected primary-expression before ‘(’ token
GeneticEngine.hpp:20:53: erreur: expected primary-expression before ‘...’ token
template <typename ... Args>
T* run_while(bool (*f)(const T&,Args& ...), const int size_enf, Args& ... args)
{
void (GeneticThread<T>::*ptm)(bool (*)(T const&, Args&...), int, Args&...) = &GeneticThread<T>::func;
std::thread(ptm, islands[0], f, size_enf, args ...);
}

Try:
std::thread(&GeneticThread<T>::func<Args...>, islands...
func is now a template function. You have to specify its template parameters to be able to take its address.

Related

g++ fails to resolve template function overload

With the following code g++ fails:
template <typename X = int, typename T, typename ...R>
inline void func(const T&, R...) {}
template <typename T>
struct S {};
template <typename X = int, typename T, typename ...R>
inline void func(const S<T>&, R...) {}
int main() {
func(42);
func(S<int>()); // OK
func(S<int>(), 1); // NOK
func<int>(S<int>(), 1); // NOK
}
with:
<source>: In function 'int main()':
<source>:13:21: error: call of overloaded 'func(S<int>, int)' is ambiguous
func(S<int>(), 1); // NOK
^
<source>:13:21: note: candidates are:
<source>:2:17: note: void func(const T&, R ...) [with X = int; T = S<int>; R = {int}]
inline void func(const T&, R...) {}
^
<source>:8:17: note: void func(const S<T>&, R ...) [with X = int; T = int; R = {int}]
inline void func(const S<T>&, R...) {}
^
<source>:14:26: error: call of overloaded 'func(S<int>, int)' is ambiguous
func<int>(S<int>(), 1); // NOK
^
...
Reproducible with gcc v4.8.1 and v9.1. Compiles with clang (v3.0.0 and v8.0.0), icc (v13.0.1 and v19.0.1), msvc (v19.14 and v19.20).
Is the code valid or is this a bug in gcc?
EDIT: Thanks everyone, your feedback was helpful for me. FYI, bug 90642 has been filed; looking forward for a definite answer.
Interesting question. I think what you run into here is overload resolution, more specifically partial ordering rules for template specialization
I quote:
Informally "A is more specialized than B" means "A accepts fewer types than B".
I think the clang is correct to compile that and the resulution should take the second candiate
template <typename X = int, typename T, typename ...R>
inline void func(const S<T>& t, R... p) {}
Because in case the first argument is not of type S<T>, it is no longer viable and thus more specialized.

Unresolved overloaded function type when attempting to pass a function as an argument

I receive the following error when attempting to compile a lone C++ testing file under G++ with C++11 in place.
spike/cur_spike.cpp: In function ‘int main()’:
spike/cur_spike.cpp:60:44: error: no matching function for call to ‘callFunctionFromName(<unresolved overloaded function type>, std::__cxx11::string&)’
callFunctionFromName (outputLine, param);
^
spike/cur_spike.cpp:49:7: note: candidate: template<class funcT, class ... Args> funcT callFunctionFromName(funcT (*)(Args ...), Args ...)
funcT callFunctionFromName (funcT func(Args...), Args... args) {
^
spike/cur_spike.cpp:49:7: note: template argument deduction/substitution failed:
spike/cur_spike.cpp:60:44: note: couldn't deduce template parameter ‘funcT’
callFunctionFromName (outputLine, param);
^
Here's the code.
#include <iostream>
#include <string>
template <typename T>
void outputLine (T text) {
std::cout << text << std::endl;
}
template <typename funcT>
funcT callFunctionFromName (funcT func()) {
return func ();
}
template <typename funcT, typename... Args>
funcT callFunctionFromName (funcT func(Args...), Args... args) {
return func (args...);
}
int main () {
std::string param = "Testing...";
callFunctionFromName (outputLine, param);
return 0;
}
I'm currently building this on a Linux system using G++, this code snippet contains all code related to this issue. I'm particularly intrigued about the fact that the compiler is unable to deduce the template parameter funcT for some reason, even though the outputLine function has a clear return type of void.
Setting a pointer of outputLine using void (*outputLinePtr)(std::string) = outputLine and using the pointer as the argument instead does nothing. Any help would be much appreciated.
You can manually set template argument.
callFunctionFromName (outputLine<std::string>, param);

using std::result_of to determine the return type of a template argument

I think the snippet of code is self explanatory, but basically the template function ExecFunc should be able to execute another function and return its result. I know I can achieve similar results using decltype instead of result_of, but this question is to understand why what I've written does not work: the snippet does not compile on gcc v4.9.2.
This is what I have:
#include <type_traits>
int f(int i)
{
return i;
}
template<class F, class T>
auto ExecFunc(F f, T arg) -> typename std::result_of<F()>::type
{
return f(arg);
}
int main() {
auto a = ExecFunc(f, 3);
return 0;
}
and this is the compiler output:
prova.cpp: In function ‘int main()’:
prova.cpp:15:26: error: no matching function for call to ‘ExecFunc(int (&)(int), int)’
auto a = ExecFunc(f, 3);
^
prova.cpp:15:26: note: candidate is:
prova.cpp:9:6: note: template<class F, class T> typename std::result_of<F()>::type ExecFunc(F, T)
auto ExecFunc(F f, T arg) -> typename std::result_of<F()>::type
^
prova.cpp:9:6: note: template argument deduction/substitution failed:
prova.cpp: In substitution of ‘template<class F, class T> typename std::result_of<F()>::type ExecFunc(F, T) [with F = int (*)(int); T = int]’:
prova.cpp:15:26: required from here
prova.cpp:9:6: error: no type named ‘type’ in ‘class std::result_of<int (*())(int)>’
N.B.
this question might look like a duplicate of this one but the accepted solution doesn't work for me (at least, as far as I can tell I have incorporated the solution in my code).
The function you have is int f(int i) but you are calling F() which is unknown. std::result_of<F()>::type should be std::result_of<F(T)>::type.
Live Example
The problem is with the parameter of result_of, it should be:
-> typename std::result_of<F(T)>::type
This is the perfect time to use decltype
template<class F, class T>
auto ExecFunc(F f, T arg) -> decltype(f(arg))

Parameters pack passing issue

I don't understand how to distinguish explicitly specified first function argument (int test in the code below) from the rest.
Is it possible to do the following?
#include <utility>
struct Foo {
Foo(int i, float j):i(i),j(j){}
int i;
float j;
};
template <typename C, typename ... Args>
C createOK(Args && ... args) {
C c = C(std::forward<Args>(args) ...);
return c;
}
template <typename C, typename ... Args>
C createBad(int test, Args && ... args) {
//say here I want to do something with `test`
//and pass all the rest of the arguments to `createOK`
return createOK(std::forward<Args>(args) ...); //how do I do that?
}
int main() {
createOK<Foo>(1,2.0f); //this works
createBad<Foo>(100, 1, 2.0f); //this doesn't
return 0;
}
The compiler errors:
./test.cpp: In instantiation of ‘C createBad(int, Args&& ...) [with C = Foo; Args = {int, float}]’:
./test.cpp:25:32: required from here
./test.cpp:19:49: error: no matching function for call to ‘createOK(int, float)’
return createOK(std::forward<Args>(args) ...); //how do I do that?
^
./test.cpp:19:49: note: candidate is:
./test.cpp:10:3: note: template<class C, class ... Args> C createOK(Args&& ...)
C createOK(Args && ... args) {
^
./test.cpp:10:3: note: template argument deduction/substitution failed:
./test.cpp:19:49: note: couldn't deduce template parameter ‘C’
return createOK(std::forward<Args>(args) ...); //how do I do that?
Please try using <C>.
Hope this helps.

gcc 4.7 about Variadic Templates/ decltype /std::forward

char foo()
{
std::cout<<"foo()"<<std::endl;
return 'c';
}
void foo(char &&i)
{
std::cout<<"foo(char &&i)"<<std::endl;
}
struct pipe {};
template<class OP>
struct Flow;
template<>
struct Flow<pipe> {
template<class L,class R>
static auto apply(L&& l,R &&r)->decltype(r(std::forward<L>(l))) {
return r(std::forward<L>(l));
}
};
template<class L,class R,class E>
struct Pipe;
template<class F,class...ARGS>
auto eval(F& f,ARGS&&... arg)->decltype(f(std::forward<ARGS>(arg)...))
{
return f(std::forward<ARGS>(arg)...);
}
template<class L,class R,class E,class...ARGS>
auto eval(Pipe<L,R,E>&f,ARGS&&... arg)->decltype(Flow<E>::apply(eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs))
{
return Flow<E>::apply(eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs);
}
template<class L,class R,class E>
struct Pipe {
L lhs;
R rhs;
Pipe(L &l,R& r):lhs(l),rhs(r) {
}
template<class...ARGS>
auto operator()(ARGS&&... arg)->decltype(eval<L,R,E >(*this,std::forward<ARGS>(arg)...)) {
return eval<L,R,E >(*this,std::forward<ARGS>(arg)...);
}
};
void streamtest()
{
void (*foo1)(char &&)=foo;
void (*foo2)(int ,int ,short )=foo;
char (*foo3)()=foo;
Pipe<char(*)(),void(*)(char&&),pipe> pp(foo3,foo1);
pp(1);
}
I want write a pipe Library for function transfer. but error Let me confused:
\FEstream.cpp: In function 'void streamtest()':
\FEstream.cpp:117:9: error: no match for call to '(Pipe<char (*)(), void (*)(char&&), pipe>) (int)'
\FEstream.cpp:98:8: note: candidate is:
\FEstream.cpp:104:13: note: template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe]
\FEstream.cpp:104:13: note: template argument deduction/substitution failed:
\FEstream.cpp: In substitution of 'template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe] [with ARGS = {int}]':
\FEstream.cpp:117:9: required from here
\FEstream.cpp:104:13: error: no matching function for call to 'eval(Pipe<char (*)(), void (*)(char&&), pipe>&, int)'
\FEstream.cpp:104:13: note: candidates are:
\FEstream.cpp:88:6: note: template<class F, class ... ARGS> decltype (f((forward<ARGS>)(eval::arg)...)) eval(F&, ARGS&& ...)
\FEstream.cpp:88:6: note: template argument deduction/substitution failed:
\FEstream.cpp:104:13: note: cannot convert '*(Pipe<char (*)(), void (*)(char&&), pipe>*)this' (type 'Pipe<char (*)(), void (*)(char&&), pipe>') to type 'char (*&)()'
\FEstream.cpp:93:6: note: template<class L, class R, class E, class ... ARGS> decltype (Flow<E>::apply(eval(f.lhs, (forward<ARGS>)(eval::arg)...), f.rhs)) eval(Pipe<L, R, E>&, ARGS&& ...)
\FEstream.cpp:93:6: note: template argument deduction/substitution failed:
\FEstream.cpp: In substitution of 'template<class L, class R, class E, class ... ARGS> decltype (Flow<E>::apply(eval(f.lhs, (forward<ARGS>)(arg)...), f.rhs)) eval(Pipe<L, R, E>&, ARGS&& ...) [with L = char (*)(); R = void (*)(char&&); E = pipe; ARGS = {int}]':
\FEstream.cpp:104:13: required by substitution of 'template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe] [with ARGS = {int}]'
\FEstream.cpp:117:9: required from here
\FEstream.cpp:93:6: error: no matching function for call to 'eval(char (*&)(), int)'
\FEstream.cpp:93:6: note: candidate is:
\FEstream.cpp:88:6: note: template<class F, class ... ARGS> decltype (f((forward<ARGS>)(eval::arg)...)) eval(F&, ARGS&& ...)
\FEstream.cpp:88:6: note: template argument deduction/substitution failed:
\FEstream.cpp: In substitution of 'template<class F, class ... ARGS> decltype (f((forward<ARGS>)(arg)...)) eval(F&, ARGS&& ...) [with F = char (*)(); ARGS = {int}]':
\FEstream.cpp:93:6: required by substitution of 'template<class L, class R, class E, class ... ARGS> decltype (Flow<E>::apply(eval(f.lhs, (forward<ARGS>)(eval::arg)...), f.rhs)) eval(Pipe<L, R, E>&, ARGS&& ...) [with L = char (*)(); R = void (*)(char&&); E = pipe; ARGS = {int}]'
\FEstream.cpp:104:13: required by substitution of 'template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe] [with ARGS = {int}]'
\FEstream.cpp:117:9: required from here
\FEstream.cpp:88:6: error: too many arguments to function
Process terminated with status 1 (0 minutes, 0 seconds)
what's happening?Is it my error,or gcc's not C++11 compliant?
////////////////////////////////////////////////////////////////////////////////////////////
thanks Dave S.but ,code is only simplification.In fact, I use templateEval::eval:
template<class L,class R,class E>
struct Pipe;
template<class F>
struct Eval {
template<class...ARGS>
static auto eval(F&f,ARGS&&... arg)->decltype(f(std::forward<ARGS>(arg)...)) {
return f(std::forward<ARGS>(arg)...);
}
};
template<class L,class R,class E>
struct Eval<Pipe<L,R,E> > {
static auto eval(Pipe<L,R,E>&f)->decltype(Flow<E>::apply(f.lhs,f.rhs)) {
return Flow<E>::apply(f.lhs,f.rhs);
}
template<class...ARGS>
static void eval(Pipe<L,R,E>&f,ARGS&&...arg) {
static_assert(!std::is_same<E,pipe>::value,
"multiple input for expression\nsample: auto expr=wrap(foo1)<var1|foo2 ;call expr(var2) instead of expr()");
}
};
template<class L,class R>
struct Eval<Pipe<L,R,pipe> > {
template<class...ARGS>
static auto eval(Pipe<L,R,pipe>&f,ARGS&&... arg)->decltype(Flow<pipe>::apply(Eval<L>::eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs)) {
return Flow<pipe>::apply(Eval<L>::eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs);
}
};
template<class L,class R,class E>
struct Pipe {
L lhs;
R rhs;
Pipe(L &l,R& r):lhs(l),rhs(r) {
}
template<class...ARGS>
auto operator()(ARGS&&... arg)->decltype(Eval<Pipe>::eval(*this,std::forward<ARGS>(arg)...)) {
return Eval<Pipe>::eval(*this,std::forward<ARGS>(arg)...);
}
};
void streamtest()
{
void (*foo1)(char &&)=foo;
void (*foo2)(int ,int ,short )=foo;
char (*foo3)()=foo;
Pipe<char(*)(),void(*)(char&&),pipe> pp(foo3,foo1);
//pp(); //no call!
}
error is:
FEstream.cpp: In instantiation of 'struct Eval >':
FEstream.cpp:121:9: required from 'struct Pipe'
FEstream.cpp:134:45: required from here
FEstream.cpp:110:18: error: invalid use of incomplete type
'struct Pipe'
FEstream.cpp:115:8: error: declaration of 'struct Pipe
void (*)(char&&), pipe>'
FEstream.cpp:110:18: error: invalid use of incomplete type
'struct Pipe'
FEstream.cpp:115:8: error: declaration of 'struct Pipe
void (*)(char&&), pipe>'
Process terminated with status 1 (0 minutes,
0 seconds) 6 errors, 0 warnings
Pipe::operator()(ARGS&&... arg) is a template member function.why I declaring variable Pipe(pp) Cause an error? it Should not be instantiated because I have not used itenter code here
anybody?
and I forget a status when eval function use by Pipe like
template<class...ARGS>
auto operator()(ARGS&&... arg)->decltype(eval(*this,std::forward<ARGS>(arg)...)) {
return eval(*this,std::forward<ARGS>(arg)...);
}
not
template<class...ARGS>
auto operator()(ARGS&&... arg)->decltype(eval<L,R,E>(*this,std::forward<ARGS>(arg)...)) {
return eval<L,R,E>(*this,std::forward<ARGS>(arg)...);
}
will error like reece:
template instantiation depth exceeds maximum of 900 .....
Seems to be select Eval(F&.... instead of eval(Pipe&f..... when not specify a template parameter
It's having trouble due to an argument mismatch, somewhere in your call chain. So, we can do it manually to find the problem.
Pipe<char(*)(),void(*)(char&&),pipe> pp(foo3,foo1); is using foo3, which takes 0 arguments as its L, and foo1, which takes an char rvalue-reference as R. And E is your marker structure pipe
When invoked with the int 1.
pp(1) calls eval<L,R,E>(*this, 1), which in turn calls
Flow<E>::apply(eval(foo3,1),foo1).
First, the inner eval is called. This attempts to determine the declval of foo3(1), however, foo3 was declared to take 0 arguments. This causes a compilation failure, which results in the substitution failures you're getting.
Edit: With the changed question, your problem is now you're creating a specialization of Eval for Pipe, but Eval is attempting to use fields of Pipe in it's return declaration (via decltype), and Pipe is doing the same. You're going to have to break that cycle so something can be defined first, or at least set it up so that the cycle isn't introduced in the function declaration, so you can define the methods after you've fully defined both types.
I'm not sure what the Eval class is attempting to accomplish. One solution might be to remove that altogether and simply have Pipe::operator() invoke the method more directly.
I'm building this on Ubuntu with gcc 4.6 (I don't have a version of gcc 4.7 to try) so YMMV.
gcc 4.6 : g++-4.6 -std=c++0x test.cpp
void (*foo2)(int ,int ,short )=foo; -- there is no version of foo matching this signature, so I commented it out.
error: expected a type, got ‘pipe’ -- pipe appears to be defined elsewhere, so renamed it to pipe_.
error: invalid use of ‘this’ at top level -- gcc 4.6 does not like auto operator()->decltype(*this) syntax, so replaced *this with Pipe<L,R,E>(lhs,rhs).
error: no match for call to ‘(Pipe<char (*)(), void (*)(char&&), pipe_>) (int)’ -- gcc 4.6 is failing to match the operator(). Here is where I am puzzled.
clang 3.1 : clang -std=c++11 test.cpp
same mismatched foo declaration as gcc
same "expected 'pipe' to be a type" error as gcc
error: no matching function for call to object of type 'Pipe<char (*)(), void (*)(char &&), pipe_>' when calling operator()
Ok. Both gcc and clang indicate an issue with the operator() definition.
template<class...ARGS>
auto operator()(ARGS&&... arg)->decltype(eval<L,R,E >(*this,std::forward<ARGS>(arg)...));
Here you are calling eval with *this and the forwarded arguments. There are two versions of eval:
template<class F,class...ARGS>
auto eval(F& f,ARGS&&... arg)->decltype(f(std::forward<ARGS>(arg)...));
and:
template<class L,class R,class E,class...ARGS>
auto eval(Pipe<L,R,E>&f,ARGS&&... arg)->decltype(Flow<E>::apply(eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs));
Now, because eval is a function and all arguments are specified in its arguments, you don't need to specify them explicitly. Doing so like:
eval<L,R,E >(*this,std::forward<ARGS>(arg)...)
is telling the compiler that the first argument is L which it is not, it is Pipe<L,R,E>.
Changing the operator() definition to:
template<class...ARGS>
auto operator()(ARGS&&... arg)->decltype(eval(*this,std::forward<ARGS>(arg)...));
now crashes clang and gcc!
EDIT: Ok, now trying the new version with gcc 4.7 I now get:
test.cpp:30:10: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) substituting ‘template<class _Tp> constexpr _Tp&& std::forward(typename std::remove_reference<_Tp>::type&&) [with _Tp = int]’
test.cpp:30:10: required by substitution of ‘template<class L, class R, class E, class ... ARGS> decltype (Flow<E>::apply(eval(f.lhs, (forward<ARGS>)(arg)...), f.rhs)) eval(Pipe<L, R, E>&, ARGS&& ...) [with L = char (*)(); R = void (*)(char&&); E = pipe_; ARGS = int]’
test.cpp:41:17: required by substitution of ‘template<class ... ARGS> decltype (eval(Pipe(((Pipe*)this)->Pipe<L, R, E>::lhs, ((Pipe*)this)->Pipe<L, R, E>::rhs), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe_] [with ARGS = {int}]’
test.cpp:25:10: required by substitution of ‘template<class F, class ... ARGS> decltype (f((forward<ARGS>)(eval::arg)...)) eval(F&, ARGS&& ...) [with F = Pipe<char (*)(), void (*)(char&&), pipe_>; ARGS = {int}]’
with the recursion between 41:17 (Pipe<L,R,E>::operator()) and 25:10 (eval<F,ARGS>()), so it is not picking up the Pipe specialization of eval. Now I am stuck again.