如何检查模板参数是否为 std::variant?

How to check if template argument is std::variant?

本文关键字:是否 std 参数 variant 何检查 检查      更新时间:2023-10-16

我想编写自己的容器MyContainer。它实现了一个 emplace 方法来就地构造对象。

template<typename T>
MyContainer<T>::emplace(Args ... args)
{
// Some construction code ....
*_cursor = T(args...);
_cursor++;
return *item;
}

不过,我想始终返回Allocator类型。尽管如果模板参数T的类型为std::variant,这将成为问题。我想做一个 SFINAE,选择适合std::variant的过载。

template<typename T>
template<typename Allocator, typename ... Args>
Allocator&
MyContainer<T>::emplace(Args ... args)
{
// Some construction code ....
*_cursor = T(Allocator(args...)); // T is std::variant, Allocator is one variant of T.
T* item = _cursor;
_cursor++;
return std::get<Allocator>(*item); // Here I want to return the correct variant
}

(我知道编译器可以根据我是否提供Allocator模板参数来选择重载。但是我想创建我的容器,以便为特定类型的子类型以及 std::variant/union 类型提供一个 emplace 方法。所以我不是在寻找那些答案)。

这是使用专用化来解开模板类型的一个相当基本的情况:

#include <variant>
#include <type_traits>
#include <iostream>
#include <string>
template<typename T> struct is_variant : std::false_type {};
template<typename ...Args>
struct is_variant<std::variant<Args...>> : std::true_type {};
template<typename T>
inline constexpr bool is_variant_v=is_variant<T>::value;
int main()
{
std::cout << is_variant_v<int> << std::endl;
std::cout << is_variant_v<std::string> << std::endl;
std::cout << is_variant_v<std::variant<int, double>> << std::endl;
return 0;
}

这是你的基本蓝图。在模板中,您可以使用它,也许在if constexpr中执行适当的逻辑。或者将其用作更复杂的专业化的构建块。

相关文章: