Should std::visit work on class derived from std::variant?

Viewed 276

This is my code (adapted from an example on cppreference):

#include <iostream>
#include <variant>

class foo : public std::variant<int, float> {
public:
  foo(int v) : std::variant<int,float>(v) {}
  foo(float v) : std::variant<int,float>(v) {}
};

int main() {
  foo v = 5;

  std::visit([](auto &&arg) {
    using T = std::decay_t<decltype(arg)>;
    if constexpr (std::is_same_v<T, int>)
      std::cout << "int: " << arg << std::endl;
    else if constexpr (std::is_same_v<T, float>)
      std::cout << "float: " << arg << std::endl;
  }, v);
}

clang (8.0.0) eats it and correctly outputs

int: 5

However, both gcc (9.1.0) and Visual Studio 17 give an error message when compiling this. So my question is: Is this correct code according to the specification?

Replacing v in the call with static_cast<std::variant<int, float>>(v) makes all three compilers successfully compile the code, so the main question is whether std::visit should accept a value of a type derived from std::variant.

0 Answers
Related