从 const ¶meter 到 ¶meter 的无效转换似乎是在胡说八道?
Invalid conversion from const ¶meter to ¶meter seems to be nonsense?
我只是好奇。我正在传递指向带有签名
的函数的指针
void printCommandReceived(const CommandDescriptor &descriptor)
作为带有签名的构造函数的第三个参数
CommandLogFilter::CommandLogFilter(QSharedPointer<LogServer> logServer, QObject *parent,
void (*preprocessValidCommand)(CommandDescriptor &descriptor))
g++ 编译器出错:
error: invalid conversion from ‘void (*)(const CommandDescriptor&)’ to ‘void (*)(CommandDescriptor&)’ [-fpermissive]
根据我的理解,对非常量对象的引用应该可以用作对常量对象参数的引用的参数。因此,具有接受非常量对象引用的函数指针类型的参数应该满足于(并从中进行隐式转换)类型为函数指针的参数,它甚至接受 const 对象引用。
我哪里错了?
void (*)(const CommandDescriptor&)
和void (*)(CommandDescriptor&)
是两种完全不同的、不相关的类型。
关于const
有很简单的规则:X*
可以转换成X const*
,X**
可以转换成X const * const *
等等。引用也一样。不允许其他任何内容。
注意规则不允许在类型的任何位置任意添加或删除const
,例如X**
不能转换为X const **
。对于函数参数的位置也是如此:您不能在那里添加或删除 const
以获得兼容的类型。
是否可以扩展这些规则以适应像您这样的情况并保持一致?大概是这样。但他们不是。
C++ 在有限的情况下可以隐式添加或删除 const
。你 运行 变成了一个无法完成的地方。不这样做的原因可能很简单 "describing those cases which are safe would be hard, and standards writers are lazy and conservative".
作为解决方法,您可以这样做:
CommandLogFilter bob(
logServer,
parent,
[](CommandDescriptor &descriptor) {
return printCommandReceived(descriptor);
}
);
因为无状态 lambda 可以隐式转换为指向与其签名匹配的函数的指针。
我不喜欢必须在那里显式签名,但是没有办法用模板 "auto" lambda 做类似的事情并且不幸地推导出签名。
我只是好奇。我正在传递指向带有签名
的函数的指针void printCommandReceived(const CommandDescriptor &descriptor)
作为带有签名的构造函数的第三个参数
CommandLogFilter::CommandLogFilter(QSharedPointer<LogServer> logServer, QObject *parent,
void (*preprocessValidCommand)(CommandDescriptor &descriptor))
g++ 编译器出错:
error: invalid conversion from ‘void (*)(const CommandDescriptor&)’ to ‘void (*)(CommandDescriptor&)’ [-fpermissive]
根据我的理解,对非常量对象的引用应该可以用作对常量对象参数的引用的参数。因此,具有接受非常量对象引用的函数指针类型的参数应该满足于(并从中进行隐式转换)类型为函数指针的参数,它甚至接受 const 对象引用。
我哪里错了?
void (*)(const CommandDescriptor&)
和void (*)(CommandDescriptor&)
是两种完全不同的、不相关的类型。
关于const
有很简单的规则:X*
可以转换成X const*
,X**
可以转换成X const * const *
等等。引用也一样。不允许其他任何内容。
注意规则不允许在类型的任何位置任意添加或删除const
,例如X**
不能转换为X const **
。对于函数参数的位置也是如此:您不能在那里添加或删除 const
以获得兼容的类型。
是否可以扩展这些规则以适应像您这样的情况并保持一致?大概是这样。但他们不是。
C++ 在有限的情况下可以隐式添加或删除 const
。你 运行 变成了一个无法完成的地方。不这样做的原因可能很简单 "describing those cases which are safe would be hard, and standards writers are lazy and conservative".
作为解决方法,您可以这样做:
CommandLogFilter bob(
logServer,
parent,
[](CommandDescriptor &descriptor) {
return printCommandReceived(descriptor);
}
);
因为无状态 lambda 可以隐式转换为指向与其签名匹配的函数的指针。
我不喜欢必须在那里显式签名,但是没有办法用模板 "auto" lambda 做类似的事情并且不幸地推导出签名。