1

This does not work out of box:

std::vector<int> a{1,2,3};
std::vector<int> b{2,3,4};

for (auto [f, s] : boost::combine(a, b)) {
    std::cout << f << ' ' << s << std::endl;
}

But this answer contains a quite small fragment of C++ code that suddenly makes this to work.

namespace std {
    template <typename T, typename U>
    struct tuple_size<boost::tuples::cons<T, U>>
        : boost::tuples::length<boost::tuples::cons<T, U>>
    { };

    template <size_t I, typename T, typename U>
    struct tuple_element<I, boost::tuples::cons<T, U>>
        : boost::tuples::element<I, boost::tuples::cons<T, U>>
    { };
}

The author, however, advises against using it in production.

Can this fragment crash my code under any circumstances, or it is just some organizational reason not to use this way to iterate over the loop?

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93

2 Answers2

2

Can this fragment crash my code under any circumstances, or it is just some organizational reason not to use this way to iterate over the loop?

If an update to boost adds specialisations like those, your program might suddenly break.

The likely scenario is that boost adds equivalently specialised specialisations, and the breakage is a compile time error.

Another scenario is that something else in boost starts using that specialisation, and you end up with different translation units using different partial specialisations for identical instantiations. This makes your program ill-formed (no diagnostic required)

[temp.class.spec]/1

A partial specialization shall be declared before the first use of a class template specialization that would make use of the partial specialization as the result of an implicit or explicit instantiation in every translation unit in which such a use occurs; no diagnostic is required.

(emphasis added)

Caleth
  • 52,200
  • 2
  • 44
  • 75
1

Can this fragment crash my code under any circumstances, or it is just some organizational reason not to use this way to iterate over the loop?

It could possible crash it, but what it does do is offer a point for your code to have undefined behavior. You don't "own" boost so you don't dictate what specializations of things in the standard boost may provide. If, at some point in the future boost decides to add this support, which very well may happen, then you now have two definitions of tuple_size and tuple_element which is an ODR violation. Not only is it undefined behavior, but no diagnostic is required so you may never even know something is wrong until it manifest itself in some strange and obscure way.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402