https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93283
Bug ID: 93283
Summary: Partial specialization not specializing any parameters
is allowed with alias templates
Product: gcc
Version: 9.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: omerfaruko at gmail dot com
Target Milestone: ---
Partial specializations with template aliases are allowed even if they don't
specialize any template arguments.
Taken from https://stackoverflow.com/q/59756201/7771076.
https://godbolt.org/z/Ne9Tav
// okay
#include <type_traits>
template<typename T, bool>
using sfinae_t = T;
template <typename T>
struct Test;
template <typename T>
struct Test<sfinae_t<T, true>> {};
Test<int> t;
// fail
#include <type_traits>
template<typename T>
using sfinae_t = T;
template <typename T>
struct Test;
template <typename T>
struct Test<sfinae_t<T>> {};
Test<int> t;
Error message for the latter:
<source>:10:8: error: partial specialization 'struct Test<T>' does not
specialize any template arguments; to define the primary template, remove the
template argument list
10 | struct Test<sfinae_t<T>> {};
| ^~~~~~~~~~~~~~~~~
<source>:7:8: note: primary template here
7 | struct Test;
|
There is a separate discussion on whether this is valid:
https://godbolt.org/z/ztuRSq
#include <type_traits>
template<typename T, typename... Ts>
using sfinae_t = T;
template<typename T, bool... Bs>
using sfinae_v_t = sfinae_t<T, typename std::enable_if<Bs>::type...>;
template <typename T>
struct Test;
template <typename T>
struct Test<sfinae_v_t<T, std::is_integral_v<T>>> {};
void f() {
Test<int> t;
}
This compiles fine with gcc (possibly due to above bug), but not with
clang/icc/MSVC.
The last one is actually useful for specializing std::hash, std::tuple_size,
std::tuple_element etc. based on user's template types.
Thanks.