Boost从1.77升级到1.85编译器错误

问题描述 投票:0回答:1

我已经升级了 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(
    ^
c++ boost boost-json
1个回答
0
投票

我对这个编译感到惊讶。我认为

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
调用以下线路:

enter image description here

最终通过

发送
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_const
T
X::Command
is
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 提出问题来询问

  • 改变是否是有意的
  • 这个重大改变的理由是什么
© www.soinside.com 2019 - 2024. All rights reserved.