あなたはGCCとクランのテンプレート引数tc3<1 or more>::a<zero or more>
、任意の数のため、このコードを使用することができます。
#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;
}
However, while the following code is accepted by Clang, it is rejected by GCC:
この次のコードは、前のみinstantinationedクランに受け入れられますが、エラーが発生した後にされています
template <typename ...Ts>
struct tc2 {
template <typename ...Us>
using b = std::add_pointer<Ts...,Us...>;
};
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> {};
このは一つだけtamplteの引数を取ることができますこのコードをサポートするために行われます:
typedef std::add_pointer<bool(int, int)>::type ptr4; // bool(*)(int,int)
注:clangは 'tc2 :: b <>'のようなインスタンス化を拒否しますが、 'tc2 <> :: b 'を受け入れます。 –
Holt
これは意味がありますか?いずれのバリデーショナルな記述の長さを専門とするのでしょうか?私はそれを決定するものは見ませんので、具体的な実装になるかもしれませんが、私は未定義の行動である可能性があります – kirinthos
["プログラムは不正であり、診断は必要ありません:\ [... \]有効なすべての特殊化variadicテンプレートの空のテンプレートパラメータパック "](http://eel.is/c++draft/temp.res#8)が必要です。 –