0

I want to partially specialize a class for when the first template parameter is not a POD-type. Here's what I came up with:

godbolt

#include <iostream>
#include <type_traits>
 
template <typename T, bool = std::is_pod<T>>
struct A
{
    void print()
    {
        std::cout << "POD\n";
    }
};

template <typename T>
struct A<T, false>
{
    void print()
    {
        std::cout << "Non-POD\n";
    }
};
 
int main()
{
    A<int> a;
    A<std::string> c;
    a.print();
    c.print();
}

However this doesn't compile and yields three types of errors (repeated for the string case):

<source>:4:43: error: expected primary-expression before '>' token
    4 | template <typename T, bool = std::is_pod<T>>
      |                                           ^~
<source>: In function 'int main()':
<source>:24:10: error: template argument 2 is invalid
   24 |     A<int> a;
      |          ^                ^
<source>:26:7: error: request for member 'print' in 'a', which is of non-class type 'int'

How would I do this? I already tried naming the default template argument (bool = ) but to no avail. Also adding all three parameters to the specialized template list doesn't help either.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
glades
  • 3,778
  • 1
  • 12
  • 34

1 Answers1

5

is_pod<T> itself is a class type that cannot be converted to bool, you should use ::value to get its value

template <typename T, bool = std::is_pod<T>::value>
                                           // ^^^^^
struct A { };

It's worth noting that is_pod has been deprecated in C++20, for simple data types you should use is_standard_layout, and for trivial data types you should use the is_trivial.

See Why is std::is_pod deprecated in C++20?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90