restricting c++ template usage to POD types

#include <type_traits>

template<typename T>
class myclass
{
    static_assert(std::is_pod<T>::value, "T must be POD");

    // stuff here...
};

The above will cause a compilation error if you pass a non-POD type as the template parameter. This solution requires C++11 for the <type_traits> header and static_assert keyword.

EDIT: You can also implement this in C++03 if your compiler supports TR1 (most do):

#include <tr1/type_traits>

template<typename T>
class myclass
{
    static char T_must_be_pod[std::tr1::is_pod<T>::value ? 1 : -1];

    // stuff here...
};

While the static_assert probably suffices in most cases, using enable_if and tag dispatch gives greater flexibility to the users of your class by the ways of SFINAE. Consider:

#include <type_traits>
#include <string>
#include <iostream>
template <typename T,
    class=typename std::enable_if< std::is_pod<T>::value >::type>
struct myclass
{
    typedef T value_type;
    T data;
};

template <typename T>
void enjoy(T)
{
    std::cout << "Enjoying T!" << std::endl;
}

template <typename T>
void enjoy(typename myclass<T>::value_type)
{
    std::cout << "Enjoying myclass<T>::value_type!" << std::endl;
}

int main()
{
    enjoy<int>(int()); // prints: Enjoying myclass<T>::value_type!
    enjoy<std::string>(std::string()); // SFINAE at work - prints: enjoying T!
    myclass<int> i; // compiles OK
    //myclass<std::string> s; // won't compile - explicit instantiation w/non-POD!
}

Now if you remove the 2nd template argument from myclass definition, and instead, like others have suggested, add a

  static_assert(std::is_pod<T>::value, "POD expected for T");

inside the class, the second line in main() will just fail to compile, triggering the static_assert.

That said, the errors from static_assert are much more friendly to human observer, than those from the failed enable_if. So, if static_assert works for you, go for it. Otherwise, if you do need to be friendlier to generic programming around your class, consider adding an explanatory comment around enable_if:

 // POD expected for T
 class=typename std::enable_if< std::is_pod<T>::value >::type>

unless everyone around you is C++11-fluent.

In real life, it's a good idea to explain why T must be POD both for static_assert and for the comment texts.


If you have C++11 support std::is_pod should do exactly what you need. Use it with std::enable_if or with tag dispatch. For example something like this:

template <typename T, typename Enable = void>
class Test;

template<typename T>
class Test<T, typename std::enable_if<std::is_pod<T>::value, void>::type>
{};

int main() {
    Test<int> t1;
    //Test<std::string> t2; <-this will not compile
}