John P John P - 4 months ago 11
C++ Question

Can a template template be specialized for fundamental types like regular templates?

I have written the following code to infix a templated class:

template<template<typename...> class C, typename A, typename B>
struct infix_t
typedef C<A, B> type;

template<template<typename...> class C, class A>
constexpr infix_t<C, A> operator<(A, infix_t<C>)
return {};

template<template<typename...> class C, typename A, typename B>
constexpr C<A, B> operator>(infix_t<C, A>, B)
return {};

This allows me to write
a <same_as> b
has type
. However, if the type of
is a fundamental type, I get
template template argument has different template parameters...
; if I try to redeclare
to accept fundamental types, I get
template argument ... must be a class template or alias template
. I thought that templates over typenames could accept fundamentals anyway. Is this because it's a template template, and the rules are different, or am I just approaching this wrong?


To expand and modify the solution by @Yakk a bit, here's a version that allows compile-time comparison of types

#include <type_traits>

template<template<class...> class Op, class... Args>
struct infix {};

template<template<class...> class Op, class L>
constexpr infix<Op, L> operator<(L, infix<Op>)
{ return {}; }

template<template<class...> class Op, class L, class R>
constexpr Op<L, R> operator>(infix<Op, L>, R)
{ return {}; }

constexpr auto same_as  = infix<std::is_same>{};

template<int N>
constexpr auto int_c = std::integral_constant<int, N>::value;

int main()
    static_assert( int_c<0> <same_as> int_c<0> );
    static_assert( !(int{} <same_as> char{}) );

Live Example