我有一组模板类,我想将它们放入 std::variant
中。下面的工作,但相当丑陋(我在变体中有更多的类,有很多模板参数)。
template <typename T>
struct Type1
{ };
template <typename B, typename C>
struct Type2
{ };
template <typename A, typename B, typename C>
using Variant = std::variant<Type1<A>, Type2<B,C>>;
是否可以用类似的方式“隐藏”模板参数? (不编译)
template <typename A>
using Type1T = Type1<A>
template <typename B, typename C>
using Type2T = Type2<B, C>
using Variant = std::variant<Type1T, Type2T>
error: type/value mismatch at argument 1 in template parameter list for 'template class std::variant'
添加 typename
似乎也不起作用。
最佳答案
您不能使用 std::variant
要做到这一点。您可以使用 std::any
, 但你不能 visit
一个any
.
问题是 Type1
和 Type2
不是类型,它们是类型模板。 Type1
的实例化无穷 , 就 visit
而言,它们都是不相关的类型很关心。
我建议你制作非模板Type1Base
你得出Type1<T>
来自,并拥有一个std::variant<std::unique_ptr<Type1Base>, std::unique_ptr<Type2Base>, ...>
编辑 - 甚至 template_variant
不可能,无法恢复所选模板的哪个实例是事件成员。如果那是可能的,那么您会遇到这样的复杂情况,即每个 访问者都必须对每个 模板的每个 实例进行重载。
原始尝试:
您可以编写自己的模板变体,其中包含类似于 std::any
的成员组合和 std::variant
template<template<class...> class ... Templates>
class template_variant
{
std::any value;
public:
// constructors, operator=, etc
// Observers
constexpr std::size_t index() const noexcept; // Which template this contains
const std::type_info& type() const noexcept; // returns the typeid of the contained value
// Modifiers
template <template<typename...> class T, class... Args>
T<Args...>&
emplace(Args&&... args)
{
value.emplace<T<Args...>>(std::forward<Args>(args)...);
}
template <size_t I, class... Args>
template_variant_alternative_t<I, variant, Args...>&
emplace(Args&&... args)
{
value.emplace<template_variant_alternative_t<I, variant, Args...>>(std::forward<Args>(args)...);
}
void swap( template_variant& rhs ) noexcept;
// Non-member functions
friend template <std::size_t I, template<class...> class ... Templates, class... Args>
constexpr template_variant_alternative_t<I, template_variant<Templates...>, Args...>&
std::get(template_variant<Templates...>& v)
{
try
{
return std::any_cast<template_variant_alternative_t<I, template_variant<Templates...>, Args...>&>(v.value);
}
catch (std::bad_any_cast & e)
{
throw bad_template_variant_access(e);
}
}
// and &&, and const&, and const&&
template <template<class...> class T, template<class...> class ... Templates, class... Args>
constexpr T<Args...>&
std::get(template_variant<Templates...>& v)
{
try
{
return std::any_cast<T<Args...>&>(v.value);
}
catch (std::bad_any_cast & e)
{
throw bad_template_variant_access(e);
}
}
// and &&, and const&, and const&&
// etc.
};
template <std::size_t I, typename Variant, class... Args>
struct template_variant_alternative;
template <std::size_t I, template<class...> class ... Templates, class... Args>
struct template_variant_alternative<I, template_variant<Templates...>, Args...>
{
using type = // apply Args... to Ith template in Templates
};
template <std::size_t I, typename Variant, class... Args>
using template_variant_alternative_t = template_variant_alternative<I, Variant, Args...>::type;
关于c++ - 在 std::variant 中隐藏模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49669750/