Code:
#include <iostream>
#include <string>
#include <vector>
#include <variant>
struct ignore
{
template <typename T>
void operator()([[maybe_unused]]const T&)
{
std::cout << "other type" << std::endl;
}
};
template <class... Ts>
struct overloaded_ignore : ignore, Ts...
{
overloaded_ignore(Ts...) : ignore(){}
using Ts::operator()...;
using ignore::operator();
};
int main()
{
std::variant<int,float,std::string> my_var = std::string("helloworld");
// std::variant<int,float,std::string> my_var = 5.0F;
// std::variant<int,float,std::string> my_var = 3;
std::visit(overloaded_ignore{
[](const int& t)
{
std::cout << "int var: " << t << std::endl;
},
[](const std::string& t)
{
std::cout << "string var: " << t << std::endl;
}
}, my_var);
return 0;
}
I expect to output "string var: helloworld", but the "other type" is outputed.
How to fix this?
Note: the ignored operator()
is required.
Just add the const
-qualifier to ignore::operator()
as the lambda's operator()
is const
-qualified by default:
struct ignore
{
template <typename T>
void operator()([[maybe_unused]]const T&) const // <--
{
std::cout << "other type" << std::endl;
}
};
template <class... Ts>
struct overloaded_ignore : ignore, Ts...
{
overloaded_ignore(Ts...) : ignore(){}
using Ts::operator()...;
using ignore::operator();
};
(Since overloaded_ignore{...}
is a prvalue, this makes the non-const
ignore::operator()
a better match before)