Basic information
- source code is below this text.
- compiles with nearly every compiler not older than 5 years (gcc 6, ...)
- compiles NOT with MS VC up to MS VC 2019 16.27
- looks like there's a problem using a variadic template as a argument prototype of a function pointer more than once.
Questions:
- code wrong or compiler wrong??
- any possibility to write this more elegant and more standard conform so MS VS compiles it?
- output at the end of the code is from compiler explorer.
#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
*/
Aucun commentaire:
Enregistrer un commentaire