Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Consider the following code:
- template<typename>
- struct One {};
- template<typename, typename>
- struct Two {};
- template<template<typename...> class TTP, typename...>
- struct SS;
- #ifdef TEST_TTP
- template<template<typename> class OneParam,
- typename... Ts>
- struct SS<OneParam, Ts...> {};
- template<template<typename, typename> class TwoParam,
- typename... Ts>
- struct SS<TwoParam, Ts...> {};
- #else // TEST_TTP
- template<template<typename> class OneParam,
- typename TParam>
- struct SS<OneParam, TParam> {};
- template<template<typename, typename> class TwoParam,
- typename TParam1,
- typename TParam2>
- struct SS<TwoParam, TParam1, TParam2> {};
- #endif // TEST_TTP
- int main() {
- SS<One, int> ssoi;
- SS<Two, int, int> sstii;
- }
- This code will compile properly on Clang, GCC, and MSVC, if `TEST_TTP` isn't defined. However, if it _is_ defined...
- * The code compiles properly on GCC, indicating that it recognises that `OneParam` and `TwoParam` are distinct from `TTP` in the primary template.
- * Clang fails to recognise that `OneParam` specialises `TTP`, causing it to emit two errors (the first being that the partial specialisation doesn't specialise any template parameters, and the second being that `OneParam` conflicts with the previously-declared template template parameter). It then emits similar errors for `TwoParam` (the first is identical, while the second says that the template template parameter has too many parameters), and an error for each instantiation of `SS` (because it considers the template to be undefined), for a total of 6 errors.
- * MSVC emits similar errors to Clang, but more concisely: It emits C3855 (`OneParam` is incompatible with the primary template), and a C2079 (variable uses undefined type) for each instantiation of `SS`, for a total of 3 errors.
- Demonstrated live [on Coliru][1].
- ----
- From my testing:
- **GCC allows a template with a template template parameter which takes a variadic parameter pack to be partially specialised based solely on the number of parameters that template template parameter takes. Clang and MSVC do not.**
- template<template<typename...> class T> struct S;
- template<template<typename> class T> struct S<T> {}; // Only works with GCC.
- template<template<typename, typename> class T> struct S<T> {}; // Only works with GCC.
- **Clang and MSVC are fine with this if other parameters are also specialised, however.**
- template<template<typename...> class T, typename... Ts> struct S;
- template<template<typename> class T,
- typename TParam>
- struct S<T, TParam> {};
- template<template<typename, typename> class T,
- typename TParam1,
- typename TParam2>
- struct S<T, TParam1, TParam2> {};
- It would thus appear that either the former isn't legal C++, or it isn't properly supported by Clang and MSVC. So, the question is this:
- **Considering this, what is the proper, legal syntax for partially specialising a template, which contains a template template parameter, based on the number of parameters that template template parameter takes? If there is no legal syntax for this, is supporting it a GCC extension and/or bug?**
- <sup>If a full record of the tests I performed, along with the original example which prompted this question, are desired, please see the edit history.</sup>
- [1]: http://coliru.stacked-crooked.com/a/f145f13504935246
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement