我试图理解 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...)
都会受到赞赏。