我怎样才能让 public 方法仅在模板具有特定类型时显示?
how can I have a public method only show up when the template has a specific type?
我有一个模板,旨在接受 int、float、double、char 和 std::string。
我希望一个方法仅在模板类型名称为 std::string
时才存在
这可能吗?
使用 SFINAE 和类型特征来实现这种功能。编译器将简单地丢弃另一个
候选函数。由于 C++11 enable_if 是 SFINAE 之上的包装器,如果您可以访问 C++11 及更高版本的支持,则可以直接使用 enable_if
如果您可以使用 C++20,则可以在所需方法上使用 requires
表达式,使其仅在某些情况下可用。
#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
顾名思义,无论 T
是什么,它始终可用。 Foo<T>::conditionallyAvailable
仅在 T
为 std::string
时可用。
C++17版本有点丑。我们必须制作 conditionallyAvailable
方法模板,然后在方法上放置一些 SFINAE 约束:
#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 和 C++11 版本与 C++17 版本类似,除了需要扩展 enable_if_t
和 is_same_v
.
我有一个模板,旨在接受 int、float、double、char 和 std::string。
我希望一个方法仅在模板类型名称为 std::string
这可能吗?
使用 SFINAE 和类型特征来实现这种功能。编译器将简单地丢弃另一个 候选函数。由于 C++11 enable_if 是 SFINAE 之上的包装器,如果您可以访问 C++11 及更高版本的支持,则可以直接使用 enable_if
如果您可以使用 C++20,则可以在所需方法上使用 requires
表达式,使其仅在某些情况下可用。
#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
顾名思义,无论 T
是什么,它始终可用。 Foo<T>::conditionallyAvailable
仅在 T
为 std::string
时可用。
C++17版本有点丑。我们必须制作 conditionallyAvailable
方法模板,然后在方法上放置一些 SFINAE 约束:
#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 和 C++11 版本与 C++17 版本类似,除了需要扩展 enable_if_t
和 is_same_v
.