Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过boost的递归对。自boost 1.62以来的变量已中断_C++_Boost_Boost Variant - Fatal编程技术网

C++ 通过boost的递归对。自boost 1.62以来的变量已中断

C++ 通过boost的递归对。自boost 1.62以来的变量已中断,c++,boost,boost-variant,C++,Boost,Boost Variant,我正在处理的代码使用递归对。在简化的示例中,该类型包含一个由字符串和int或另一个这样的对组成的对。这应该(并且是)通过以下方式实现: #include <boost/variant.hpp> #include <string> using namespace std; typedef boost::make_recursive_variant < std::pair < std::string , boost:

我正在处理的代码使用递归对。在简化的示例中,该类型包含一个由
字符串
int
或另一个这样的对组成的对。这应该(并且是)通过以下方式实现:

#include <boost/variant.hpp>
#include <string>

using namespace std;

typedef boost::make_recursive_variant
      < std::pair
        < std::string
        , boost::variant<int, boost::recursive_variant_>
        >
      >::type recursivePair;

typedef boost::variant< int
                    , recursivePair
                    > intPairVariant;

using sType = boost::variant<pair<string, string>, int>;

void foo(){
    sType bar(make_pair("aa", "bb"));
    recursivePair xxx(std::make_pair (std::string("s"), intPairVariant()));
    recursivePair yyy(std::make_pair (string("s"), 5));
    recursivePair zzz(std::make_pair ("s", 5));
}
这只适用于一种类型。其他人也同样失败


有人知道为什么这不再有效,以及如何修复吗?

我认为您实际上遇到了类似于
std::pair
的更改,如图所示:

自c++11以来,std::pair的隐式转换更少。确实,您的代码确实编译了boost<1.62,但从本质上看,这似乎是一个错误,至少在c++11模式下是这样

在C++11中,您可以执行以下操作:

std::make_pair(s, i); // s is std::string, i is int
这将导致
std::pair
。接下来,您不仅要求将
std::pair
隐式转换为
std::pair
,而且还希望使用该转换的结果作为所分配变量的初始值设定项

在C++的所有部分中,这要求两个隐式转换,编译器永远无法解决使用它的过载。

所以,实际上您的代码有点草率,因为它使用了Boost变体可能不具备的“回旋余地”。这是一个突破性的变化,但新的行为似乎更有意义

另一个音符 您正在使用单个元素创建递归变量。那是。。。有点奇怪

通过将
std::pair
结构属性隐藏在
variant
的第一层下,这会使类型系统“紧张”一点

直接使用
std::pair

Pair xxx("s", V{});
Pair yyy("s", 5);
Pair zzz{};
#include <boost/variant.hpp>
#include <string>
#include <iostream>

namespace mylib {

    struct V;
    using Pair = std::pair<std::string, V>;

    struct V : boost::variant<int, boost::recursive_wrapper<Pair> > {
        using base = boost::variant<int, boost::recursive_wrapper<Pair> >;

        V() = default;
        V(V&&) = default;
        V(V const&) = default;
        V& operator=(V&&) = default;
        V& operator=(V const&) = default;

        V(int i) : base(i) {}
        V(std::string const& key, V value);
    };

    V::V(std::string const& key, V value) : base{Pair{std::move(key), std::move(value)}} {}

    static inline std::ostream& operator<<(std::ostream& os, Pair const& p) {
        return os << "{" << p.first << "," << p.second << "}";
    }
}

int main() {
    using mylib::V;
    V xxx("s", mylib::V{});
    V yyy("s", 5);
    V zzz{};
    V huh("s", {"more", {"intricate", {"nested", { "truths", 42} } } });

    V simple = 5;
    simple = {"simple", 5};
    simple = {"not_so_simple", simple};

    std::cout << "xxx:" << xxx << "\n";
    std::cout << "yyy:" << yyy << "\n";
    std::cout << "zzz:" << zzz << "\n";
    std::cout << "huh:" << huh << "\n";
    std::cout << "simple:" << simple << "\n";
}
我能想象的最无聊的事情是:

#include <boost/variant.hpp>
#include <string>

using namespace std;

typedef std::pair<std::string,
    boost::make_recursive_variant<int, std::pair<std::string, boost::recursive_variant_> >::type >
    recursivePair;

typedef boost::variant<int, recursivePair> intPairVariant;

int main() {
    recursivePair xxx(std::string("s"), intPairVariant());
    recursivePair yyy(string("s"), 5);
    recursivePair zzz("s", 5);
}
但是
make_pair
在这三种情况下都是多余的

有趣的变化 也许你可以做一些更像

struct V;
using Pair = std::pair<std::string, V>;

struct V : boost::variant<int, boost::recursive_wrapper<Pair> > {
    using base = boost::variant<int, boost::recursive_wrapper<Pair> >;
    using base::base;
    using base::operator=;
};
帮助建设者 使用派生结构而不是普通变量的好处在于,实际上可以消除构造函数的歧义:

Pair xxx("s", V{});
Pair yyy("s", 5);
Pair zzz{};
#include <boost/variant.hpp>
#include <string>
#include <iostream>

namespace mylib {

    struct V;
    using Pair = std::pair<std::string, V>;

    struct V : boost::variant<int, boost::recursive_wrapper<Pair> > {
        using base = boost::variant<int, boost::recursive_wrapper<Pair> >;

        V() = default;
        V(V&&) = default;
        V(V const&) = default;
        V& operator=(V&&) = default;
        V& operator=(V const&) = default;

        V(int i) : base(i) {}
        V(std::string const& key, V value);
    };

    V::V(std::string const& key, V value) : base{Pair{std::move(key), std::move(value)}} {}

    static inline std::ostream& operator<<(std::ostream& os, Pair const& p) {
        return os << "{" << p.first << "," << p.second << "}";
    }
}

int main() {
    using mylib::V;
    V xxx("s", mylib::V{});
    V yyy("s", 5);
    V zzz{};
    V huh("s", {"more", {"intricate", {"nested", { "truths", 42} } } });

    V simple = 5;
    simple = {"simple", 5};
    simple = {"not_so_simple", simple};

    std::cout << "xxx:" << xxx << "\n";
    std::cout << "yyy:" << yyy << "\n";
    std::cout << "zzz:" << zzz << "\n";
    std::cout << "huh:" << huh << "\n";
    std::cout << "simple:" << simple << "\n";
}

有一个更好的(不是那么“无聊”的解决方案,重复性更少:我在评估你的解决方案并将其应用于“真实事物”时发现了这一点。在我接受你的回答之前,这只是基于“我想要什么?”(因此评论):你的第一个变体在叮当声上失败了:此外,我更喜欢它,因为它在真实事物上的重复更少。虽然你的“ctor帮助”看起来不错,但我希望它不是必需的。哦,这似乎是Clang3.8中的一个bug,在Clang3.9中得到了解决:Boost变体的更改列在发行说明中
xxx:{s,0}
yyy:{s,5}
zzz:0
huh:{s,{more,{intricate,{nested,{truths,42}}}}}
simple:{not_so_simple,{simple,5}}