STL-pair-like triplet class - do I roll my own?

24,304

Solution 1

No, don't roll your own. Instead, take a look at std::tuple - it's a generalization of std::pair. So here's a value-initialized triple of ints:

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

If you want, you can have a type alias for triples only:

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

Solution 2

If you're using C++11, you can use std::tuple.

If you're using C++03, then you'll either need to resort to rolling your own (which isn't too hard), or using tuple from Boost.

Solution 3

I think you need something like this:

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;
}

Examples of usage:

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;

I'm using this and it is enough for my purposes... If you want different types, though, just do some modifications:

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;
}

And the usage will be very similar:

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;
Share:
24,304
einpoklum
Author by

einpoklum

Made my way from the Olympus of Complexity Theory, Probabilistic Combinatorics and Property Testing to the down-to-earth domain of Heterogeneous and GPU Computing, and now I'm hoping to bring the gospel of GPU and massive-regularized parallelism to DBMS architectures. I've post-doc'ed at the DB architecture group in CWI Amsterdam to do (some of) that. I subscribe to most of Michael Richter's critique of StackOverflow; you might want to take the time to read it. If you listen closely you can hear me muttering "Why am I not socratic again already?"

Updated on April 17, 2021

Comments

  • einpoklum
    einpoklum about 3 years

    I want to use a triplet class, as similar as possible to std::pair. STL doesn't seem to have one. I don't want to use something too heavy, like Boost. Is there some useful FOSS non-restrictive-license triplet class I could lift from somewhere? Should I roll my own? Should I do something else entirely?

    Edit: About std::tuple...

    Is there really no benefit to a triplet-specific class? I mean, with tuple, I can't do

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

    now can I? Won't I have to typedef individual-type-combination triples?

  • einpoklum
    einpoklum about 7 years
    Oh no, a triplet class should definitely not be a subclass of std::pair. A triplet is not a kind-of-a-pair, like a std::pair<T,U> is not a subclass of T nor of U.
  • Bert Bril
    Bert Bril about 7 years
    I don't see your point. A twin is a pair where Tand U are the same class, triplet has 3 of the same type. Any triplet can be usef where any twin can be usef.
  • einpoklum
    einpoklum about 7 years
    That is absolutely not true. With a pair, you rely on there being exactly two pieces of data; with a triplet, you make a contradictory assumption. Not only can they not be subclasses, but they cannot be used interchangeably.
  • Bert Bril
    Bert Bril about 7 years
    Sorry I disagree. Anywhere you need a twin you can use a triplet, but not the other way around. That's exactly the idea of inheritance, the LSK applies perfectly. Moreover, because the members are called 'first' and 'second' parameterized functions and classes get exactly what they need from a pair even when in fact they operate on a triplet. Very standard and very OK.
  • user1956185
    user1956185 over 6 years
    There is a small mistake in your code. The definition of make_triplet should be triplet<T1,T2,T3> make_triplet(const T1 &m1, const T2 &m2, const T3 &m3)
  • Neo li
    Neo li almost 3 years
    Get error message when I use: vector< triplet<double, double, double> > v; v.emplace_back(1,2,3);