为什么将 `printf` 作为模板函数参数传递成功但 `cos` 失败(msvc 19)?
Why passing `printf` as template function argument succeeds but `cos` failed (msvc 19)?
我在 link 上玩了一下在线 C++ 编译器。但是下面的代码片段在使用 msvc v19.latest.
编译时失败了
#include <iostream>
#include <cmath>
#include <cstdio>
template<class F, class...L>
void test(F f, L...args) {
std::cout<< "res = " << f(args...) << '\n';
}
int main()
{
test(cos, 0.1); #1
test(printf, "%s", "aaa"); #2
}
怎么可能2号线没问题,1号线就通不过呢?
MSVC 对以下代码很满意,但这次轮到 GCC 拒绝了。 MSVC 的 iostream 文件包括 cmath 头和 GCC #undefs cos :)
#include <stdio.h>
#include <math.h>
//#include <iostream>
template<class F, class...L>
void test(F f, L...args) {
f(args...);
}
int main()
{
test(cos, 0.1);
test(printf, "%s", "aaa");
}
从 c++20 开始,第二个答案中提出了另一个问题,并已在这个问题中得到解决
它失败了,因为 cos
是 msvc 中的重载函数。这意味着至少有 3 个不同版本的 cos
:
float cos(float arg);
double cos(double arg);
long double cos(long double arg);
编译器无法猜测您要使用哪个,但您可以使用 static_cast
来帮助它,如下所示:
int main()
{
test(static_cast<double(*)(double)>(cos), 0.1);
test(printf, "%s", "aaa");
}
not allowed获取库函数的地址(有少数例外),然后将其作为参数传递给另一个函数。任何这样做的尝试都是未指明的行为。 MSVC 拒绝你的程序是对的,gcc 接受它也是对的(并且可能格式化你的硬盘并向你的老板发送讨厌的电子邮件)。
我在 link 上玩了一下在线 C++ 编译器。但是下面的代码片段在使用 msvc v19.latest.
编译时失败了#include <iostream>
#include <cmath>
#include <cstdio>
template<class F, class...L>
void test(F f, L...args) {
std::cout<< "res = " << f(args...) << '\n';
}
int main()
{
test(cos, 0.1); #1
test(printf, "%s", "aaa"); #2
}
怎么可能2号线没问题,1号线就通不过呢?
MSVC 对以下代码很满意,但这次轮到 GCC 拒绝了。 MSVC 的 iostream 文件包括 cmath 头和 GCC #undefs cos :)
#include <stdio.h>
#include <math.h>
//#include <iostream>
template<class F, class...L>
void test(F f, L...args) {
f(args...);
}
int main()
{
test(cos, 0.1);
test(printf, "%s", "aaa");
}
从 c++20 开始,第二个答案中提出了另一个问题,并已在这个问题中得到解决
它失败了,因为 cos
是 msvc 中的重载函数。这意味着至少有 3 个不同版本的 cos
:
float cos(float arg);
double cos(double arg);
long double cos(long double arg);
编译器无法猜测您要使用哪个,但您可以使用 static_cast
来帮助它,如下所示:
int main()
{
test(static_cast<double(*)(double)>(cos), 0.1);
test(printf, "%s", "aaa");
}
not allowed获取库函数的地址(有少数例外),然后将其作为参数传递给另一个函数。任何这样做的尝试都是未指明的行为。 MSVC 拒绝你的程序是对的,gcc 接受它也是对的(并且可能格式化你的硬盘并向你的老板发送讨厌的电子邮件)。