Reputation: 21
Basic information
Questions:
#include <iostream>
// https://godbolt.org/
// https://www.onlinegdb.com/online_c++_compiler
// http://cpp.sh/
using std::ostream;
using uint = unsigned int;
template <typename... Ts>
uint Start (const char* String,
void (*fn1) (Ts...), // Works fine with every compiler
Ts&&... args)
{
std::cout << String << ' ' << __FUNCTION__ << '\n';
if (fn1) fn1 (args...);
return 1;
}
template <typename... Ts>
uint Start (const char* String,
void (*fn1) (Ts...),
void (*fn2) (Ts...), // Microsoft-Compiler makes trouble here using Ts a second time... ***
Ts&&... args)
{
std::cout << String << ' ' << __FUNCTION__ << '\n';
if (fn1) fn1 (args...);
if (fn2) fn2 (args...);
return 2;
}
template <typename... Ts>
uint Start (const char* String,
void (*fn1) (Ts...),
void (*fn2) (Ts...),
void (*fn3) (Ts...),
Ts&&... args)
{
std::cout << String << ' ' << __FUNCTION__ << '\n';
if (fn1) fn1 (args...);
if (fn2) fn2 (args...);
if (fn3) fn3 (args...);
return 3;
}
void Fn1 (double x) { std::cout << __FUNCTION__ << ' ' << 1*x << '\n'; }
void Fn2 (double x) { std::cout << __FUNCTION__ << ' ' << 2*x << '\n'; }
void Fn3 (double x) { std::cout << __FUNCTION__ << ' ' << 3*x << '\n'; }
void Gn1 (double x, int y) { std::cout << __FUNCTION__ << ' ' << 1*x << ' ' << 1*y << '\n'; }
void Gn2 (double x, int y) { std::cout << __FUNCTION__ << ' ' << 2*x << ' ' << 2*y << '\n'; }
void Gn3 (double x, int y) { std::cout << __FUNCTION__ << ' ' << 3*x << ' ' << 3*y << '\n'; }
int
main()
{
std::cout << __FUNCTION__ << '\n';
std::cout << Start <double> ("Test 1" , Fn1, 12.34) << " returned\n";
std::cout << Start <double> ("Test 2" , Fn1, Fn2, 12.34) << " returned\n";
std::cout << Start <double> ("Test 3a", Fn1, Fn2, Fn3, 12.34) << " returned\n";
std::cout << Start <double, int> ("Test 3b", Gn1, Gn2, Gn3, 12.34, 42) << " returned\n";
std::cout << Start <double, int> ("Test 3c",
*[] (double x, int y) -> void { std::cout << __FUNCTION__ << ' ' << 1*x << ' ' << 1*y << '\n'; },
*[] (double x, int y) -> void { std::cout << __FUNCTION__ << ' ' << 2*x << ' ' << 2*y << '\n'; },
*[] (double x, int y) -> void { std::cout << __FUNCTION__ << ' ' << 3*x << ' ' << 3*y << '\n'; },
3.14159, 42) << " returned\n";
return 0;
}
/*
x64 msvc v19.27
exxample.cpp
<source>(59): error C2660: 'Start': function does not take 4 arguments
<source>(11): note: see declaration of 'Start'
<source>(61): error C2672: 'Start': no matching overloaded function found
<source>(61): error C2782: 'uint Start(const char *,void (__cdecl *)(Ts...),Ts &&...)': template parameter 'Ts' is ambiguous
<source>(11): note: see declaration of 'Start'
<source>(61): note: could be 'double'
<source>(61): note: or 'void(__cdecl &)(double), double'
<source>(63): error C2660: 'Start': function does not take 6 arguments
<source>(11): note: see declaration of 'Start'
<source>(66): error C2593: 'operator *' is ambiguous
<source>(66): note: could be 'built-in C++ operator*(main::<lambda_00de9a703c525e1d30b87861a11e038f>::<lambda_typedef_cdecl>)'
<source>(66): note: or 'built-in C++ operator*(main::<lambda_00de9a703c525e1d30b87861a11e038f>::<lambda_typedef_vectorcall>)'
<source>(66): note: while trying to match the argument list '(main::<lambda_00de9a703c525e1d30b87861a11e038f>)'
<source>(66): error C2100: illegal indirection
<source>(67): error C2593: 'operator *' is ambiguous
<source>(67): note: could be 'built-in C++ operator*(main::<lambda_63e8d9ca3695b55d9d6dc9dda05048f3>::<lambda_typedef_cdecl>)'
<source>(67): note: or 'built-in C++ operator*(main::<lambda_63e8d9ca3695b55d9d6dc9dda05048f3>::<lambda_typedef_vectorcall>)'
<source>(67): note: while trying to match the argument list '(main::<lambda_63e8d9ca3695b55d9d6dc9dda05048f3>)'
<source>(67): error C2100: illegal indirection
<source>(68): error C2593: 'operator *' is ambiguous
<source>(68): note: could be 'built-in C++ operator*(main::<lambda_9769e2f1b0b076d22151082820474129>::<lambda_typedef_cdecl>)'
<source>(68): note: or 'built-in C++ operator*(main::<lambda_9769e2f1b0b076d22151082820474129>::<lambda_typedef_vectorcall>)'
<source>(68): note: while trying to match the argument list '(main::<lambda_9769e2f1b0b076d22151082820474129>)'
<source>(68): error C2100: illegal indirection
Compiler returned: 2
*/
Upvotes: 1
Views: 82
Reputation: 21
Found the following std::vector
solution, actually I would prefer a
std::array<N>
solution (see at the end):
#include <iostream>
#include <vector>
using std::ostream;
using std::cout;
using uint = unsigned int;
template <typename... Ts>
uint Start (const char* String,
std::vector <void (*) (Ts...)> fn,
Ts&&... args)
{
cout << String << ' ' << __FUNCTION__ << '\n';
for (int i = 0; i < fn.size(); i++)
if (fn[i])
fn[i] (args...);
return fn.size();
}
void Fn1 (double x) { cout << __FUNCTION__ << ' ' << 1*x << '\n'; }
void Fn2 (double x) { cout << __FUNCTION__ << ' ' << 2*x << '\n'; }
void Fn3 (double x) { cout << __FUNCTION__ << ' ' << 3*x << '\n'; }
void Gn1 (double x, int y) { cout << __FUNCTION__ << ' ' << 1*x << ' ' << 1*y << '\n'; }
void Gn2 (double x, int y) { cout << __FUNCTION__ << ' ' << 2*x << ' ' << 2*y << '\n'; }
void Gn3 (double x, int y) { cout << __FUNCTION__ << ' ' << 3*x << ' ' << 3*y << '\n'; }
int
main()
{
cout << __FUNCTION__ << '\n';
cout << Start <double> ("Test 1" , { Fn1 }, 12.34) << " returned\n";
cout << Start <double> ("Test 2" , { Fn1, Fn2 }, 12.34) << " returned\n";
cout << Start <double> ("Test 3a", { Fn1, Fn2, Fn3 }, 12.34) << " returned\n";
cout << Start <double, int> ("Test 3b", { Gn1, Gn2, Gn3 }, 12.34, 42) << " returned\n";
cout << Start <double, int> ("Test 3c",
{ [] (double x, int y) -> void { cout << __FUNCTION__ << ' ' << 1*x << ' ' << 1*y << '\n'; },
[] (double x, int y) -> void { cout << __FUNCTION__ << ' ' << 2*x << ' ' << 2*y << '\n'; },
[] (double x, int y) -> void { cout << __FUNCTION__ << ' ' << 3*x << ' ' << 3*y << '\n'; }
},
3.14159, 42) << " returned\n";
return 0;
}
Ist there any way to write
template <size_t N> // assigning N the right value should be in the response of the compiler without any additional (){}<>[] stuff
template <typename... Ts>
uint Start (const char* String,
std::array <void (*) (Ts...), N> fn, // std::array or classic C[] array
Ts&&... args)
{
cout << String << ' ' << __FUNCTION__ << '\n';
for (int i = 0; i < N; i++)
if (fn[i])
fn[i] (args...);
return N;
}
still calling this by simple code like
cout << Start <double, int> ("Test 3b", { Gn1, Gn2, Gn3 }, 12.34, 42) << " returned\n";
Is there any way to have a automatic assigned N with other variadic arguments?
Upvotes: 1