Search code examples
c++templatestemplate-meta-programmingtype-traits

How do I use std::is_pod in a template argument?


I'm trying to get one set of behavior when something is a pod, and something else when it's not through template meta programming. I've written the below code, but I get a compilation error. I want to get:

yep
nope

but I get the following compiler error:

error C2993: 'std::is_pod<_Ty>': illegal type for non-type template parameter '__formal'

Using this code

#include <iostream>
#include <type_traits>

struct A
{
    int b;
};

struct B
{
private:
    int b;
public:
    int c;
};

template <class Z, std::is_pod<Z>>
void x()
{
    std::cout << "yep" << std::endl;
}

template <class Z>
void x()
{
    std::cout << "nope" << std::endl;
}

int main()
{
    x<A>();
    x<B>();
    return 0;
}

Any advice?


Solution

  • You need to use std::enable_if to use the value from std::is_pod in a SFINAE context. That would look like

    // only enable this template if Z is a pod type
    template <class Z, std::enable_if_t<std::is_pod_v<Z>, bool> = true>
    void x()
    {
        std::cout << "yep" << std::endl;
    }
    
    // only enable this template if Z is not a pod type
    template <class Z, std::enable_if_t<!std::is_pod_v<Z>, bool> = true>
    void x()
    {
        std::cout << "nope" << std::endl;
    }
    

    Do note that std::is_pod is deprecated in C++17 and has been removed from C++20.