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
.
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";
}
};
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