Home > Net >  how can I have a public method only show up when the template has a specific type?
how can I have a public method only show up when the template has a specific type?

Time:12-19

I have a template that is intended to take int, float, double, char and std::string. I want a method to only exist if the template typename is std::string

Is this possible?

CodePudding user response:

If you can use C 20, you can use a requires expression on the desired method to cause it to only be available under certain circumstances.

#include <iostream>
#include <string>
#include <concepts>

template<class T>
struct Foo
{
    void alwaysAvailable() { std::cout << "Always available\n"; }

    void conditionallyAvailable() requires std::same_as<T, std::string>
    {
        std::cout << "T is std::string\n";
    }
};

int main()
{
    Foo<int> fooInt;
    fooInt.alwaysAvailable();
    //fooInt.conditionallyAvailable(); // Constraint not satisfied

    Foo<std::string> fooString;
    fooString.alwaysAvailable();
    fooString.conditionallyAvailable();
}

Foo<T>::alwaysAvailable is, as the name suggests, always available no matter what T is. Foo<T>::conditionallyAvailable is only available when T is std::string.

Demo here

The C 17 version is a little uglier. We have to make conditionallyAvailable a method template and then place some SFINAE constraints on the method:

#include <type_traits>

template<class T>
struct Foo
{
    void alwaysAvailable() { std::cout << "Always available\n"; }

    template<class U = T>
    std::enable_if_t<std::is_same_v<U, T> && std::is_same_v<U, std::string>, void> conditionallyAvailable()
    {
        std::cout << "T is std::string\n";
    }
};

Demo here

C 14 and C 11 versions are similar to the C 17 version, except for needing to expand out enable_if_t and is_same_v.

CodePudding user response:

Use SFINAE along with type traits to achieve such kind of feature. Compiler will simply discard the other candidate function . Since C 11 enable_if is a wrapper on top of SFINAE , If you have access to C 11 and beyond support , you can directly use enable_if

  • Related