我意识到这是错误的,但我无法删除它
I realized this is wrong but I could not delete it
作者:这当然做不到。从下面的答案中学习。
C++我们如何执行以下操作
// fundamental language construct
type name = value ;
// for example
int x = y;
使用函数指针?
typedef (char)(*FP)(unsigned);
// AFAIK not possible in C++
FP x = y ;
我可以使用lambdas:
FP x = []( unsigned k) -> char { return char(k); }
但是我不知道没有lambda如何做到这一点。有什么想法吗?
每当你可以编写 typedef 时,你也可以编写一个没有 typedef 的变量声明,语法几乎相同。
例:
// typedef
typedef char(*FP)(unsigned);
FP x = y ;
// no typedef
char(*x)(unsigned) = y;
删除typedef
关键字,您将拥有一个变量声明。如果需要,可以在其上打上初始化。
您可以使用auto
:
auto fptr = &f;
它跳过了对 typedef 的需求并保留了一个很好的语法。
它与 Lambdas 几乎相同,但我认为很难阅读:
void my_int_func(int x)
{
std::cout << "ther param is: " << x << std::endl;
}
//
int main(int argc, char *argv[])
{
void (*foo)(int) = my_int_func;
foo(1);
但是我不知道在没有 lambda 的情况下如何做到这一点。有什么想法吗?
只是不要使用 lambda 而是使用函数:
typedef char(*FP)(unsigned);
char foo(unsigned){ return 0;}
int main() {
FP x = foo;
}
函数指针类型定义相当讨厌,如果你能更好地使用using
:
using FP = char(*)(unsigned);
现场演示
嗯...如果您使用的是 lambda,您也可以使用auto
,所以
auto x = foo;
下面是一个完整的编译示例,其中包含验证所获得类型的static_assert()
#include <type_traits>
char foo (unsigned)
{ return ' '; }
int main ()
{
auto x = foo;
static_assert( std::is_same<decltype(x), char(*)(unsigned)>::value, "!" );
}
将auto
与 lambda 一起使用的方式与使用FP
的方式相同
auto y = []() ->bool { return true; };
导致一些不同的东西:上面的y
类型是一个带有operator()
的未命名类,而不是指向该operator()
的函数指针类型。
如果你想要一个指针来函数,你必须使用运算符+
将 lambda 转换为它,因为您可以使用以下static_assert()
进行验证
auto y = +[]() ->bool { return true; };
static_assert( std::is_same<decltype(y), bool(*)()>::value, "!" );
非常感谢大家提供有用的评论的生动过山车。Reddit上的某个人,我在用户名"TheTiefMaster"下问了同样的问题,删除了这个"一行":
// also works as C
char whatever(unsigned k) { return char(k); } char(*F)(unsigned) = whatever;
让我澄清一下:我确实理解这是一行中的两个陈述。不,这里没有类型,而是一个指向同一函数的函数指针。用法:
auto x = whatever(65); // 'A'
auto y = F(66); // 'B'
然后我认为以下内容将进行函数定义及其类型声明:
// FP is a type of function whoever
char whoever(unsigned k) { return 'A'; } typedef char(*FP)(unsigned) ;
呼叫行为符合预期的人
auto w = whoever(42) ; // 'A'
FP是它开始变得有趣的地方。FP是一种类型,事实证明可以转换为该类型。
// using FP as a type
// c++ style type cast
// empty cast returns nullptr
auto fun = FP();
// calling fun() above crashes
// but it is "invocable" as per C++ rules
static_assert(std::is_invocable_v<P2F()>);
将任何参数传递给此强制转换,工作并返回非空地址:
// update: this compiles only on MSVC
// and is a bug
auto fun = FP(42);
// type of fun is char (*) (unsigned)
显然,调用这种有趣的崩溃的结果:
// reading access violation
fun(123) ;
此转换使用来自任何所需函数的实例,工作:
auto fun = FP(whatever);
// works, obviously
fun(65) ; // 'A'
为了使用这些知识,我们将使用static_cast安全地转换为我们可以调用的内容。C++型铸造太用力了,就像C型型演员一样。
// does not compile
// fun is the wrong type and can not be called
auto fun = static_cast<FP>(42);
// does compile, fun is safe to call
auto fun = static_cast<FP>(whatever);
// works, obviously
fun(65) ; // 'A'
这项调查显然远未结束。我将在别处继续讨论。
更新:
using FP = char (*)(int) ;
// must not compile, compiles under MSVC
auto oops = FP(42) ;
是MSVC中的错误,我今天报告了。
代码:
typedef char(*FP)(int);
FP x = y;
如果y
是捕获变量的 lambda 表达式,则无法使用当前C++编译器进行编译。
// Compiles OK
FP x0 = [](int k) -> char { return char(k); };
// Fails to compile
int i = 123;
FP x1 = [=](int k) -> char { return char(k); };
FP x2 = [=](int k) -> char { return char(k+i); };
FP x3 = [&](int k) -> char { return char(k+i); };
FP x4 = [i](int k) -> char { return char(k+i); };
// error: cannot convert ‘main()::<lambda(int)>’ to ‘FP {aka char (*)(int)}’
// in initialization
它无法编译的原因是作业右侧的大小x1
...x4
大于FP
的大小。
对于C++编译器进行分配x1
...x4
有效,则需要在运行时生成代码。当前的C++编译器(如GCC和clang)不支持此功能,主要是因为它会导致内存泄漏,因为C++不是垃圾回收语言。一些垃圾回收语言实现,例如官方 Go 编译器的早期版本,确实通过执行运行时代码生成来支持此类赋值。
- 如何在不强制转换每个参数的情况下删除初始值设定项列表中从 int 到 char 的缩小转换?
- 在命令行上将输入显示到数组中时如何删除 ./a.out?
- 比较 2 个向量并从第二个向量中删除在第一个 - c++ 中找不到的元素
- 删除字符串后C++检测到堆损坏
- 将类型添加到现有模板而不删除 c++17
- 将内容从第一个文件("constituencies")移动到第二个文件("temp")并在之后重命名时,我的文件被删除
- 在 c++ 中打开文件、删除标点符号并追加到另一个文件中
- 我意识到这是错误的,但我无法删除它
- 我想意识到一个接收STD ::相同参数的函数,然后称其为“如何”
- C 11/14:如何从类型中删除指针到会员
- OOP——让部分意识到它们的整体
- 何时删除添加到 std::vector 的元素
- 有没有办法意识到一个数字是否由于转换而被截断
- 在代码中使用 strcmp,编译>测试>失败,调试,意识到我忘记了 0==strcmp
- 卸载程序不会删除复制到VS2010安装程序项目中的系统文件夹。
- 将由垃圾收集器删除导出到C#的C++类
- 删除传递到函数C++中的新变量
- C++-如何删除打印到控制台的换行符
- 如何使编译器意识到模板结构
- 当一个对象改变某些值时要意识到