我试图理解cppreference为std::visit
提供的示例。以下是该链接的示例:
#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>
template<class T> struct always_false : std::false_type {};
using var_t = std::variant<int, long, double, std::string>;
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
int main() {
std::vector<var_t> vec = {10, 15l, 1.5, "hello"};
for(auto& v: vec) {
// void visitor, only called for side-effects
std::visit([](auto&& arg){std::cout << arg;}, v);
// value-returning visitor. A common idiom is to return another variant
var_t w = std::visit([](auto&& arg) -> var_t {return arg + arg;}, v);
std::cout << ". After doubling, variant holds ";
// type-matching visitor: can also be a class with 4 overloaded operator()'s
std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>)
std::cout << "int with value " << arg << '\n';
else if constexpr (std::is_same_v<T, long>)
std::cout << "long with value " << arg << '\n';
else if constexpr (std::is_same_v<T, double>)
std::cout << "double with value " << arg << '\n';
else if constexpr (std::is_same_v<T, std::string>)
std::cout << "std::string with value " << std::quoted(arg) << '\n';
else
static_assert(always_false<T>::value, "non-exhaustive visitor!");
}, w);
}
for (auto& v: vec) {
std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
}
}
我对overloaded
声明特别感兴趣:
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
第一个是有意义的 - 结构overloaded
正在为它封装的每个类型的构造函数声明。但是我不明白第二个目的。这似乎是一个类似于:
template<class... Ts> overloaded<Ts...> overloaded(Ts...);
但是函数永远不会定义,所以如何在后面的示例中使用它?如果这只是一个构造函数,那么为什么它不需要overloaded::
前缀,身体在哪里呢?我想我只是误解了尾随返回类型声明“扩展”的内容,因此对overloaded(Ts...)
声明所完成的内容的任何见解都将不胜感激。