我已经升级了 boost(见标题),但由于 Boost.JOSN 中的一些问题,我无法编译为代码。鉴于以下代码使用 Boost 1.77 成功编译,但使用 1.85 编译失败:
namespace product_namespace {
enum class Command {
enum values...
};
// tag_invoke implementation in source file, make no sense here
Command tag_invoke(const boost::json::value_to_tag<Command>& vt, boost::json::value const& jv);
void tag_invoke(const boost::json::value_from_tag& vt, boost::json::value& jv, const Command& command);
inline boost::json::value Digest() const {
Command Cmd = Command::SomeValue;
return boost::json::value{
{"cmd", Cmd}, // Compiler error here. See below
...
};
};
谁能帮我,如何解决这个问题?版本从 1.77 升级到 1.85 的失败原因是什么?
谢谢你
完整的编译器错误日志(我必须修改原始日志,以删除一些公司专有信息):
In file included from <built-in>:455:
In file included from .../cmake_pch.hxx:5:
In file included from .../pch.h:57:
In file included from ...thirdparty/boost/include/boost/json.hpp:15:
In file included from ...thirdparty/boost/include/boost/json/array.hpp:1762:
In file included from ...thirdparty/boost/include/boost/json/value.hpp:4317:
.../thirdparty/boost/include/boost/json/impl/value_ref.hpp:36:12: error: no matching constructor for initialization of 'boost::json::value'
return value(
^
.../thirdparty/boost/include/boost/json/value_ref.hpp:204:16: note: in instantiation of function template specialization 'boost::json::value_ref::from_const<product_namespace::Command>' requested here
: cf_{&from_const<T>, &t}
^
.../Request.h:189:30: note: in instantiation of function template specialization 'boost::json::value_ref::value_ref<product_namespace::Command>' requested here
{Request::NameOfCmd, Cmd},
^
.../thirdparty/boost/include/boost/json/value.hpp:247:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'const boost::json::value' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:305:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::value' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:329:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'std::nullptr_t' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:384:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'signed char' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:406:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'short' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:428:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'int' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:450:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'long' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:472:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'long long' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:494:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'unsigned char' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:516:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'unsigned short' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:538:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'unsigned int' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:560:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'unsigned long' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:582:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'unsigned long long' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:604:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'double' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:629:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::string_view' (aka 'basic_string_view<char>') for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:656:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'const char *' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:711:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'const boost::json::string' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:738:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::string' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:774:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::string_kind_t' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:828:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'const boost::json::array' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:855:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::array' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:891:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::array_kind_t' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:945:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'const boost::json::object' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:972:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::object' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:1008:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'boost::json::object_kind_t' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:1056:5: note: candidate constructor not viable: no known conversion from 'const product_namespace::Command' to 'std::initializer_list<value_ref>' for 1st argument
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:362:5: note: candidate template ignored: requirement 'std::is_same<product_namespace::Command, bool>::value' was not satisfied [with T = product_namespace::Command]
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:78:5: note: candidate constructor not viable: requires single argument 'ua', but 2 arguments were provided
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:85:5: note: candidate constructor not viable: requires single argument 'uo', but 2 arguments were provided
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:174:5: note: candidate constructor not viable: requires single argument 'sp', but 2 arguments were provided
value(storage_ptr sp) noexcept
^
.../thirdparty/boost/include/boost/json/value.hpp:201:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
value(pilfered<value> other) noexcept
^
.../thirdparty/boost/include/boost/json/value.hpp:222:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
value(value const& other)
^
.../thirdparty/boost/include/boost/json/value.hpp:271:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
value(value&& other) noexcept;
^
.../thirdparty/boost/include/boost/json/value.hpp:687:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:805:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
value(array other) noexcept
^
.../thirdparty/boost/include/boost/json/value.hpp:922:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
value(object other) noexcept
^
.../thirdparty/boost/include/boost/json/value.hpp:91:5: note: candidate constructor not viable: requires 3 arguments, but 2 were provided
value(
^
.../thirdparty/boost/include/boost/json/value.hpp:153:5: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
value() noexcept
^
.../thirdparty/boost/include/boost/json/value.hpp:99:5: note: candidate constructor not viable: requires 4 arguments, but 2 were provided
value(
^
我对这个编译感到惊讶。我认为
value_from
仅被显式调用过。
这是 Boost 1.77:
#include <boost/json/src.hpp>
#include <iostream>
namespace json = boost::json;
namespace X {
enum Command { SomeValue, b, c };
Command tag_invoke(json::value_to_tag<Command>, json::value const&) {
return {}; // TODO
}
void tag_invoke(json::value_from_tag, json::value& jv, Command const& command) {
switch (command) {
case SomeValue: jv = "SomeValue"; break;
case b: jv = "b"; break;
case c: jv = "c"; break;
}
}
} // namespace X
int main() {
X::Command Cmd = X::Command::SomeValue;
std::vector<int> vv{1, 2, 3};
std::cout << json::value{{"cmd", Cmd}} << std::endl;
std::cout << json::value{{"cmd", Cmd}, {"vec", vv}} << std::endl;
}
我们看到了
{"cmd":"SomeValue"}
{"cmd":"SomeValue","vec":[1,2,3]}
虽然我没想到,但似乎很有道理。
提升1.78-1.80工作。 Boost 1.81 不再编译。 更改日志确实提到了有关内置 value_to/value_from 支持的一些更改,但没有任何内容表明构造函数的预期更改。
查看构造函数的文档,没有提及 tag_invoke 转换。
查看实现,初始化列表导致使用 value_ref
构造函数的
this 重载。这会导致
value_ref::make_value
调用以下线路:
最终通过
发送template<class T>
value
value_ref::
from_const(
void const* p,
storage_ptr sp)
{
return value(
*reinterpret_cast<
T const*>(p),
std::move(sp));
}
令人惊讶的是,它最终出现在构造函数中
json::value::value(int, storage_ptr)
。这并不奇怪,因为 from_constT
X::Commandis
int` 中的 , which implicitly converts to
。
这是使用 GCC 14.1 和 Boost 1.86 (git@112dc7298874f5e1)。
Clang 18.1.5 有相同的结果。
根据上述分析,我们可以说初始化器列表和
from_const
工厂函数模板并不重要。让我们直接调用value
构造函数:
std::cout << json::value(X::Command::SomeValue) << std::endl;
现在,1.77会发生什么?事实上,这具有相同的行为,打印
0
。
确实,在 1.77 中
const_from
是以 value_from
的形式实现的!
template<class T>
value
value_ref::
from_const(
void const* p,
storage_ptr sp)
{
return value_from(
*reinterpret_cast<
T const*>(p),
std::move(sp));
}
此更改是在 dff6f8d4 中引入的,作为 PR#686 转换函数重构的一部分。您可以在 https://github.com/boostorg/json/issues 提出问题来询问