【问题标题】:STL-pair-like triplet class - do I roll my own?类似 STL 对的三元组类 - 我自己滚动吗?
【发布时间】:2014-01-09 10:31:28
【问题描述】:

我想使用与 std::pair 尽可能相似的三元组类。 STL 似乎没有。我不想使用太重的东西,比如Boost。是否有一些有用的 FOSS 非限制性许可三元组我可以从某个地方提升?我应该自己滚动吗?我应该完全做其他事情吗?

编辑:关于std::tuple...

三元组特定的课程真的没有好处吗?我的意思是,对于元组,我做不到

template<typename T1, typename T2, typename T3> std::tuple<T1, T2, T3> triple;

现在可以吗?我不需要对单个类型组合三元组进行 typedef 吗?

【问题讨论】:

  • 我会说std::tuple
  • 如果由于某种原因您无法访问std::tuple(例如,不符合 C++11 的编译器),请考虑使用std::pair&lt;T, std::pair&lt;U, V&gt; &gt;
  • @FrédéricHamidi:这会使元素引用变得非常麻烦和不直观。
  • 但是 std::pair 的元素引用已经不直观。您真正需要称为firstsecond 的元素的频率(而不是例如keyvalue,或namesurname)。
  • @JamesKanze:mytriple.second.secondmytriple.third 更令人困惑。

标签: c++ c++-standard-library stdtuple triplet


【解决方案1】:

不,不要自己动手。相反,请查看std::tuple - 它是std::pair 的概括。所以这是ints 的值初始化三元组:

std::tuple<int, int, int> triple;

如果需要,您可以只为三元组设置类型别名:

template<typename T1, typename T2, typename T3>
using triple = std::tuple<T1, T2, T3>;

【讨论】:

    【解决方案2】:

    如果可以使用 C++11,请使用 std::tuple

    如果没有,使用 boost::tuple

    【讨论】:

      【解决方案3】:

      如果您使用的是 C++11,则可以使用 std::tuple

      如果您使用的是 C++03,那么您要么需要自行滚动(这并不难),要么使用来自 Boost 的 tuple

      【讨论】:

        【解决方案4】:

        我认为你需要这样的东西:

        template<typename T>
        struct triplet
        {
            T first, middle, last;
        };
        
        template<typename T>
        triplet<T> make_triplet(const T &m1, const T &m2, const T &m3) 
        {
            triplet<T> ans;
            ans.first = m1;
            ans.middle = m2;
            ans.last = m3;
            return ans;
        }
        

        使用示例:

        triplet<double> aaa;
        aaa = make_triplet<double>(1.,2.,3.);
        cout << aaa.first << " " << aaa.middle << " "  << aaa.last << endl;
        
        triplet<bool> bbb = make_triplet<bool>(false,true,false);
        cout << bbb.first << " " << bbb.middle << " "  << bbb.last << endl;
        

        我正在使用它,这对我的目的来说已经足够了......不过,如果你想要不同的类型,只需进行一些修改:

        template<typename T1, typename T2, typename T3>
        struct triplet
        {
            T1 first; 
            T2 middle;
            T3 last;
        };
        
        template<typename T1, typename T2, typename T3>
        triplet<T1,T2,T3> make_triplet(const T1 &m1, const T2 &m2, const T3 &m3) 
        {
            triplet<T1,T2,T3> ans;
            ans.first = m1;
            ans.middle = m2;
            ans.last = m3;
            return ans;
        }
        

        而且用法会很相似:

        triplet<bool,string,myDouble> ccc;
        ccc = make_triplet<bool,string,double>(false,"AB",3.1415);
        ccc.middle = "PI";
        cout << ccc.first << " " << ccc.middle << " "  << ccc.last << endl;
        

        【讨论】:

        • 你的代码有一个小错误。 make_triplet的定义应该是triplet&lt;T1,T2,T3&gt; make_triplet(const T1 &amp;m1, const T2 &amp;m2, const T3 &amp;m3)
        • 使用时得到错误信息:vector&lt; triplet&lt;double, double, double&gt; &gt; v; v.emplace_back(1,2,3);
        【解决方案5】:

        要为 std::pair 添加相似性方面,您可以定义一个具有第一、第二和第三的类。我的猜测是,在这种情况下,您无法避免创建 std::pair 的子类并添加“第三个”成员。几行代码。

        此外,如果您经常将这些东西与同一类型一起使用,您也可以制作双胞胎和三胞胎课程。使用 C++-11 的“使用”轻松制作,例如:

        template <typename T> using twins = std::pair<T,T>;
        

        【讨论】:

        • 哦不,三元组绝对不应该是std::pair 的子类。三元组不是一对,就像std::pair&lt;T,U&gt; 不是T 的子类,也不是U 的子类。
        • 我不明白你的意思。双胞胎是一对,其中 T 和 U 是同一类,三胞胎有 3 个相同类型。在任何双胞胎都可以使用的地方,任何三胞胎都可以使用。
        • 这绝对不是真的。使用一对,您依赖于恰好有两条数据;对于三元组,您会做出自相矛盾的假设。它们不仅不能是子类,而且不能互换使用。
        • 对不起,我不同意。任何需要双胞胎的地方都​​可以使用三胞胎,但反之则不行。这正是继承的思想,LSK 完美适用。此外,因为成员被称为“第一个”和“第二个”参数化函数,并且类从一对中获得它们所需要的东西,即使实际上它们在三元组上运行。非常标准,非常OK。
        猜你喜欢
        • 2011-02-09
        • 2018-11-28
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-18
        • 1970-01-01
        相关资源
        最近更新 更多