连接一元参数的模板参数包

2023-12-29

虽然说,std::add_pointer是一元的,以下代码被 GCC 7.0.0 (20160608) 和 Clang 3.9.0 接受:

template <typename ...Ts>
struct tc1 {
  using a = std::add_pointer<Ts...>;
};

然而,虽然以下代码被 Clang 接受,但被 GCC 拒绝:

template <typename ...Ts>
struct tc2 {
  template <typename ...Us>
  using b = std::add_pointer<Ts...,Us...>;
};

这是有效的 C++ 吗?从语法上讲,我可以想象当包为空时逗号是一个问题,但想必在其他情况下它会被省略;例如,std::common_type接受零个或多个参数,并且以下内容对于任一编译器都没有问题:

template <typename ...Ts>
struct tc3 {
  template <typename ...Us>
  using c = std::common_type<Ts...,Us...>;
};

您可以将此代码用于任意数量的模板参数tc3<1 or more>::a<zero or more>,关于 GCC 和 Clang:

#include <type_traits>

struct A {
    template<typename ...Args> A(Args ... args) {}
};

template <typename T, typename ...Ts>
struct tc3 {
  template <typename ...Us>
  using c = std::add_pointer<T(Ts...,Us...)>;
};

int main() {
    typedef tc3<A, int, float>::template c<unsigned, double>::type  ptr;// A(*)(int,float,unsigned,double)
    typedef tc3<A>::template c<>::type ptr2;                // A(*)()
    typedef tc3<bool>::template c<int, int>::type ptr3;     // bool(*)(int,int)
    typedef std::add_pointer<bool(int, int)>::type ptr4;    // bool(*)(int,int)

    return 0;
}
  • 海湾合作委员会 7.0.0:http://melpon.org/wandbox/permlink/m7Re0kFevMjalv6s http://melpon.org/wandbox/permlink/m7Re0kFevMjalv6s
  • 铿锵4.0.0:http://melpon.org/wandbox/permlink/mXDtQRN7COxhtLN8 http://melpon.org/wandbox/permlink/mXDtQRN7COxhtLN8

然而,虽然以下代码被 Clang 接受,但却被拒绝 通过海湾合作委员会:

以下代码仅在实例化之前被 Clang 接受,但在出现错误之后:

template <typename ...Ts>
struct tc2 {
  template <typename ...Us>
  using b = std::add_pointer<Ts...,Us...>;
};
  • 错误铿锵4.0:http://melpon.org/wandbox/permlink/vpBCJHlvWk1ai1ny http://melpon.org/wandbox/permlink/vpBCJHlvWk1ai1ny
  • 错误 GCC 7.0.0:http://melpon.org/wandbox/permlink/a1rRfDI5zcUz3nau http://melpon.org/wandbox/permlink/a1rRfDI5zcUz3nau

std::add_pointer<>只能采用一个模板参数:http://en.cppreference.com/w/cpp/types/add_pointer http://en.cppreference.com/w/cpp/types/add_pointer

template< class T >
struct add_pointer;

只能在内部接受多个参数namespace细节或其他方面:

可能的实施:

namespace detail {
    template< class T, bool is_function_type = false >
    struct add_pointer {
        using type = typename std::remove_reference<T>::type*;
    };

    template< class T >
    struct add_pointer<T, true> {
        using type = T;
    };

    template< class T, class... Args >
    struct add_pointer<T(Args...), true> {
        using type = T(*)(Args...);
    };

    template< class T, class... Args >
    struct add_pointer<T(Args..., ...), true> {
        using type = T(*)(Args..., ...);
    };

} // namespace detail

template< class T >
struct add_pointer : detail::add_pointer<T, std::is_function<T>::value> {};

这样做是为了支持此代码:

typedef std::add_pointer<bool(int, int)>::type ptr4;    // bool(*)(int,int)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

连接一元参数的模板参数包 的相关文章

随机推荐