c++ - 仅对定义了函数的类型在函数模板中执行函数
问题描述
我有一个函数模板,它输入许多不同的类型。在这些类型中,只有一种具有getInt()
功能。因此,我希望代码仅针对该类型运行该函数。请提出解决方案。谢谢
#include <type_traits>
#include <typeinfo>
class X {
public:
int getInt(){
return 9;
}
};
class Y{
};
template<typename T>
void f(T& v){
// error: 'class Y' has no member named 'getInt'
// also tried std::is_same<T, X>::value
if(typeid(T).name() == typeid(X).name()){
int i = v.getInt();// I want this to be called for X only
}
}
int main(){
Y y;
f(y);
}
解决方案
如果您希望能够f
为所有具有函数成员的类型调用函数getInt
,而不仅仅是X
,您可以为函数声明 2 个重载f
:
对于具有
getInt
成员函数的类型,包括类X
对于所有其他类型,包括 class
Y
。
C++11 / C++17 解决方案
考虑到这一点,您可以执行以下操作:
#include <iostream>
#include <type_traits>
template <typename, typename = void>
struct has_getInt : std::false_type {};
template <typename T>
struct has_getInt<T, std::void_t<decltype(((T*)nullptr)->getInt())>> : std::is_convertible<decltype(((T*)nullptr)->getInt()), int>
{};
class X {
public:
int getInt(){
return 9;
}
};
class Y {};
template <typename T,
typename std::enable_if<!has_getInt<T>::value, T>::type* = nullptr>
void f(T& v) {
// only for Y
std::cout << "Y" << std::endl;
}
template <typename T,
typename std::enable_if<has_getInt<T>::value, T>::type* = nullptr>
void f(T& v){
// only for X
int i = v.getInt();
std::cout << "X" << std::endl;
}
int main() {
X x;
f(x);
Y y;
f(y);
}
现场查看。
请注意,它是在 C++17 中引入的,但如果您仅限于 C++11,那么您自己std::void_t
实现它真的很容易:void_t
template <typename...>
using void_t = void;
这里是 C++11 版本的live。
我们在 C++20 中有什么?
C++20 带来了很多好东西,其中之一就是概念。以上对 C++11/C++14/C++17 有效的东西在 C++20 中可以显着减少:
#include <iostream>
#include <concepts>
template<typename T>
concept HasGetInt = requires (T& v) { { v.getInt() } -> std::convertible_to<int>; };
class X {
public:
int getInt(){
return 9;
}
};
class Y {};
template <typename T>
void f(T& v) {
// only for Y
std::cout << "Y" << std::endl;
}
template <HasGetInt T>
void f(T& v){
// only for X
int i = v.getInt();
std::cout << "X" << std::endl;
}
int main() {
X x;
f(x);
Y y;
f(y);
}
现场查看。
推荐阅读
- rsync - Rsync 问题:忽略 --time-limit 选项
- c - 使用 C 中的 strstr() 函数打印包含子字符串的主字符串
- python - 在 3d numpy 数组中创建滚动/移动窗口
- reactjs - 如何模拟保存到 LocalStorage 的 redux 存储
- python - 如何为具有 1 列或更多列的 Pandas 数据透视表保留或显示值的列名称?
- graphics - 如何在three.js中获得圆柱映射?
- python - 不断收到“缺少 1 个必需的位置参数”,但给出了参数
- php - 使用 phpseclib3 从 Azure B2C 密钥生成公钥
- azure-functions - 使用 VS Code,如何将持久函数添加到具有目标框架 5.0 的函数应用程序
- python - 如何结合 None 和“g”命名空间?