Cap'n proto 生成的 C++ 源代码无法编译
Cap'n proto generated c++ source doesn't compile
我在使用这段 capnp 代码时遇到问题:
struct Result(Success, Error) {
union {
success @0 :Success;
error @1 :Error;
}
}
我这样创建并编译了 c++ 源代码:
capnp compile -oc++ test.capnp
g++ -o test.capnp.o test.capnp.c++ `pkg-config --cflags capnp` -std=c++11
而且我在生成的头文件中的多个位置都遇到了同样的错误(同样是 ERROR 而不是 SUCCESS):
error: type/value mismatch at argument 2 in template parameter list for ‘template<class Success, class Error> struct Result’
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
^
error: expected a type, got ‘true’
error: expected primary-expression before ‘>’ token
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
^
error: ‘::SUCCESS’ has not been declared
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
^
这是 g++ 抱怨的定义之一:
template <typename Success, typename Error>
inline ::capnp::ReaderFor<Success> Result<Success, Error>::Reader::getSuccess() const {
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers<Success>::get(
_reader.getPointerField(0 * ::capnp::POINTERS));
}
我真的不明白为什么g++不接受这个...
我使用 capnproto 0.5.3(在 0.5.2 中首次遇到此问题,然后更新以查看是否有帮助)和 g++ 4.9.2。
此答案的其余部分已过时。自 capnp 版本 0.6.0.
以来,此问题不应再出现
刚写完问题,我也想用clang测试一下,结果居然让我发现了错误。我仍然选择 post 这个问题,因为我已经写完了。问题是 KJ_IREQUIRE
是一个宏,因为宏是预处理器处理的东西,所以它们的语义非常丑陋。 Result
的模板参数中的逗号被解释为宏的参数定界符,导致在 g++ 中出现这种非常无用的错误消息,但在 clang 中会出现更好的错误消息。
要解决此问题,您可以在 KJ_IREQUIRE
的参数周围添加另一组括号。我希望这一点文档可以帮助别人!
我在使用这段 capnp 代码时遇到问题:
struct Result(Success, Error) {
union {
success @0 :Success;
error @1 :Error;
}
}
我这样创建并编译了 c++ 源代码:
capnp compile -oc++ test.capnp
g++ -o test.capnp.o test.capnp.c++ `pkg-config --cflags capnp` -std=c++11
而且我在生成的头文件中的多个位置都遇到了同样的错误(同样是 ERROR 而不是 SUCCESS):
error: type/value mismatch at argument 2 in template parameter list for ‘template<class Success, class Error> struct Result’
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
^
error: expected a type, got ‘true’
error: expected primary-expression before ‘>’ token
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
^
error: ‘::SUCCESS’ has not been declared
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
^
这是 g++ 抱怨的定义之一:
template <typename Success, typename Error>
inline ::capnp::ReaderFor<Success> Result<Success, Error>::Reader::getSuccess() const {
KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers<Success>::get(
_reader.getPointerField(0 * ::capnp::POINTERS));
}
我真的不明白为什么g++不接受这个...
我使用 capnproto 0.5.3(在 0.5.2 中首次遇到此问题,然后更新以查看是否有帮助)和 g++ 4.9.2。
此答案的其余部分已过时。自 capnp 版本 0.6.0.
以来,此问题不应再出现刚写完问题,我也想用clang测试一下,结果居然让我发现了错误。我仍然选择 post 这个问题,因为我已经写完了。问题是 KJ_IREQUIRE
是一个宏,因为宏是预处理器处理的东西,所以它们的语义非常丑陋。 Result
的模板参数中的逗号被解释为宏的参数定界符,导致在 g++ 中出现这种非常无用的错误消息,但在 clang 中会出现更好的错误消息。
要解决此问题,您可以在 KJ_IREQUIRE
的参数周围添加另一组括号。我希望这一点文档可以帮助别人!