I have two variant objects of the following type
struct FigureMove {};
struct PieceMove {};
using Move = std::variant<FigureMove, PieceMove>;
I want to supply two Move objects to a function and call different functions depending on the underlying types in the variants.
I have two different versions of the function which takes the Move objects. One taking them as separate function arguments and one taking both of them in an array.
Note, I plan on supplying always one FigureMove and one PieceMove, just their order is not clear beforehand.
bool areMovesValid(const FigureMove &figureMove0, const PieceMove &pieceMove1)
{
return {};
}
bool areMovesValid(const PieceMove &pieceMove0, const FigureMove &figureMove1)
{
return {};
}
//#define USE_ARRAY
#ifdef USE_ARRAY
bool areMovesValid(const std::array<Move, 2> &moves)
{
const auto &variantMove0 = moves[0];
const auto &variantMove1 = moves[1];
#else
bool areMovesValid(const Move &variantMove0, const Move &variantMove1)
{
#endif
return std::visit(
[variantMove1](const auto move0)
{
return std::visit(
[move0](const auto move1)
{
return areMovesValid(move0, move1);
},
variantMove1);
},
variantMove0);
}
The version taking the array throws tons of compile time errors. Using gcc or clang.
Why is that and how can I fix it?
Here is the code on godbolt.
>Solution :
return areMovesValid(move0, move1);
When not using an array parameter this results in infinite recursion for a combination of two values that are the same type, because overload resolution will pick the same areMovesValid.
When using an array parameter version: overload resolution fails, since these two parameters cannot be converted to a single std::array, and the remaining overloads don’t match.
If you choose to name the third function, the one that takes a pair of Moves as something other than areMovesValid, neither version will compile.
I plan on supplying always one
FigureMoveand onePieceMove
That’s nice, but your C++ compiler is not taking your word for it. The combination of the two std::visit calls will also generate the code paths where both parameters are both FigureMoves and PieceMoves. And that has to compile, somehow.