【问题标题】:How to make a template function enabled if one of variant's types?如果变体类型之一,如何启用模板功能?
【发布时间】:2019-08-24 15:50:57
【问题描述】:

我有一些变体using V = std::variant<A, B, C> 和一些函数foo,原型void foo(const T&)

如果V 的其中一种类型被传递(没有明确指出),则希望我的函数foo 成为std::enable_ifed。

我的V 会及时得到越来越多的类型,正因为如此,解决方案就像

template<class T,
         typename std::enable_if<
            std::is_same_v<T, A> || std::is_same_v<T, B> || std::is_same_v<T, C>,
            int>::type = 0>
void foo(const T&);

不可接受。

Here 是一种升压解决方案。

是否可以实现std::variant的逻辑?

理想情况下,类型特征应该类似于is_one_of_variants_types&lt;V, T&gt;

【问题讨论】:

  • 变体可以是任何类型;如果变体实际上不是有效的替代方案, foo 会做什么?
  • @Yakk-AdamNevraumont, foo 采用一些变体的类型,而不是变体本身。 (这些类型的变体本身可能是变体,但这不应该影响解决方案。)

标签: c++ c++17 template-meta-programming typetraits variant


【解决方案1】:
template <typename, typename>
constexpr bool is_one_of_variants_types = false;

template <typename... Ts, typename T>
constexpr bool is_one_of_variants_types<std::variant<Ts...>, T>
    = (std::is_same_v<T, Ts> || ...);

template <typename T>
auto foo(const T&)
    -> std::enable_if_t<is_one_of_variants_types<V, T>>;

DEMO

【讨论】:

    【解决方案2】:

    如果 V 的类型之一被传递(不明确指出),则希望我的函数 foo 为 std::enable_if ed。

    我想你可以简单地尝试,在 decltype() 中,在 emplace()T 值在 V 值中。

    我的意思是……如下所示

    #include <variant>
    #include <type_traits>
    
    struct A {};
    struct B {};
    struct C {};
    
    using V = std::variant<A, B, C>;
    
    template <typename T>
    auto foo (T const & t)
       -> std::void_t<decltype( std::declval<V>().emplace<T>(t) )>
     { }
    
    int main ()
     {
       foo(A{});  // compile
       // foo(0); // compilation error
     }
    

    显然,这仅适用于所有变体类型不同且具有复制构造函数(隐式或显式)的情况。

    【讨论】:

    • 感谢您的智能解决方案!请你解释一下为什么Obviously this works only if all variant types are different.
    • 因为emplace&lt;T, Args...&gt;() 方法只有在TTipes... 中恰好出现一次时才可用(给定std::variant&lt;Tipes...&gt;)。不是唯一的问题:T 必须可以从T 值构造,因此对于Tipes... 中的每种类型,您都需要一个复制构造函数(隐式,如我的示例,或显式)。所以,是的:这是一个聪明的解决方案;但有几个很大的限制。
    • 谢谢!不知道。我已经测试了你的解决方案。更多限制:类型不能不完整(即,如果在定义之前使用 foo,则前向声明的类型将无法编译),当然,对构造函数的限制是痛苦的。
    • @Nestor - 是的......不完整是另一个问题。
    猜你喜欢
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 2021-09-10
    相关资源
    最近更新 更多