代码之家  ›  专栏  ›  技术社区  ›  fatdragon

当第二个参数包括“T”时,无法推断模板参数“T”

c++
  •  0
  • fatdragon  · 技术社区  · 3 年前

    给定此模板函数:

    template <
        typename T,
        typename U,
        typename = std::enable_if<
            std::is_same_v<U, std::unique_ptr<T>> ||
            std::is_same_v<U, std::shared_ptr<T>>>>
    T foo(U val) {
      if constexpr (std::is_same_v<U, std::unique_ptr<T>>) {
        return *val;
      }
      return *val;
    }
    

    我想这样称呼它:

    int x = foo(std::make_unique<int>(1));
    

    但是,它给出了这个错误:

    Candidate template ignored: couldn't infer template argument 'T'
    

    我可以通过显式提供类型T来修复它:

    int x = foo<int>(std::make_unique<int>(1));
    

    有没有可能修正它,使它可以推断?类型清楚地嵌入在typename中 U 但它似乎并没有“传播”到 T .

    1 回复  |  直到 3 年前
        1
  •  3
  •   HolyBlackCat    3 年前

    SFINAE约束不影响模板参数推导。你的编译器必须推导 T U 首先,甚至不用看你的 enable_if_t<...> .

    我会这样做:

    #include <memory>
    #include <type_traits>
    
    namespace impl
    {
        template <typename A, template <typename...> typename B>
        struct specialization_of : std::false_type {};
    
        template <template <typename...> typename T, typename ...P>
        struct specialization_of<T<P...>, T> : std::true_type {};
    }
    
    template <typename A, template <typename...> typename B>
    concept specialization_of = impl::specialization_of<A, B>::value;
    
    
    template <typename T>
    requires specialization_of<T, std::unique_ptr> || specialization_of<T, std::shared_ptr>
    auto foo(T val)
    {
        if constexpr (specialization_of<T, std::unique_ptr>)
        {
            return *val;
        }
        return *val;
    }
    

    [我也想] std::is_same_v<U, std::function<T()>>

    然后您需要一个专门的模板来完成此任务。类似于:

    template <typename T, typename U>
    struct foo : std::false_type {};
    template <typename T, typename U>
    struct foo<std::function<T()>, U> : std::is_same<T, U> {};
    

    然后 foo<std::function<int()>, int> 是真的。