2

我在使用这段 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: 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 ‘&gt;’ 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。

4

1 回答 1

2

这个答案的其余部分已经过时了。自 capnp 版本 0.6.0 起,此问题不应再出现。


就在我写完我的问题时,我也想用 clang 测试它,它实际上让我找到了错误。我仍然选择发布这个问题,因为我已经写完了。问题在于它KJ_IREQUIRE是一个宏,并且由于宏是预处理器处理的东西,它们的语义非常难看。模板参数中的逗号Result被解释为宏的参数分隔符,导致在 g++ 中这个非常无用的错误消息,但在 clang 中更好。

要解决此问题,您可以在 的参数周围添加另一组括号KJ_IREQUIRE。我希望这篇文档可以帮助某人!

于 2015-08-14T13:28:29.663 回答