2016-06-20 14 views
8
std::add_pointer tekli, diyelim ki, birlikte aşağıdaki kod, hem GCC 7.0.0 (20.160.608) ve Clang 3.9.0 tarafından kabul

: ise,bitiştirme şablon parametre paketleri

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

Ancak Aşağıdaki kod Clang tarafından kabul edilir, GCC tarafından reddedilir: Bu geçerli C++ mı? Sözdizimsel olarak, paketlerin boş olduğu durumlarda virgülün bir sorun olduğunu düşünebilirdim, fakat muhtemelen başka durumlarda da seçilebilir; Sen GCC ve Clang üzerinde, şablon argümanları tc3<1 or more>::a<zero or more> herhangi bir sayı için bu kodu kullanabilirsiniz

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

Not: clang, tc2 :: b <> gibi örneklemeyi reddeder, ancak 'tc2 <> :: b 'seçeneğini kabul eder. – Holt

+0

bu mantıklı mı? ne varadik tanımlamanın uzunluğunu uzmanlaşır? Bunu belirleyecek bir şey görmüyorum, bu yüzden uygulamaya özgü olabilir, ama ben tanımlanamayan bir davranış olabilir düşünüyorum – kirinthos

+3

["Program bozuk biçimlidir, gerekli değilse:: \ [... \] her geçerli uzmanlık bir çeşit şablonun boş bir şablon parametre paketi "] olmasını gerektirir (http://eel.is/c++draft/temp.res#8). –

cevap

1

:

#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; 
} 
örneğin std::common_type sıfır veya daha fazla argüman ve aşağıdaki hediyeler derleyici biri için hiçbir sorun kabul Bu aşağıdaki kod yalnızca önce instantinationed ama Clang tarafından kabul edilen

However, while the following code is accepted by Clang, it is rejected by GCC:

hata var sonra:

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

template< class T > 
struct add_pointer; 

bir argüman daha fazla sadece iç namespace ayrıntılı olarak ya da bazı başka yer alabilir:

Muhtemel uygulama:

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> {}; 

Butek tamplte argüman alabilir Bu kodu desteklemek için yapılır:

typedef std::add_pointer<bool(int, int)>::type ptr4; // bool(*)(int,int)