c++ - decltype:使用指针访问类的静态成员
问题描述
我有一个模板函数f
。我将它传递给一个引用或一个指向对象的指针。该对象是 struct S
。我想知道 的大小S::my_tuple
,它是该结构的静态成员。
当我通过引用传递对象时,我可以做到这一点std::tuple_size<decltype(T::my_tuple)>::value
。
我怎样才能为指针做到这一点?这目前失败,因为my_tuple
不是S*
玩代码。
#include <tuple>
#include <type_traits>
#include <iostream>
struct S {
constexpr static auto my_tuple = std::make_tuple(1, 2, 3, 4);
};
template <typename T>
int f(const T object) {
// fails if T is a pointer
if (std::is_pointer<T>::value) {
// error
return std::tuple_size<decltype(T::my_tuple)>::value;
}
// works if T is a reference
return std::tuple_size<decltype(T::my_tuple)>::value;
}
int main() {
S my_struct;
std::cout << f(my_struct); // 4, correct size of properties
S* my_ptr = new S;
std::cout << f(my_ptr); // does not compile
}
编辑:
感谢您的支持。这是解决方案
解决方案
只需删除具有类型特征的指针:
decltype(std::remove_pointer_t<std::decay_t<T>>::my_tuple)
在const T object
,T
绝不是参考。std::decay_t<T>
例如,如果您使用通用引用 ( T&& object
) 代替,则需要。
另请注意,当您使用if
. 如果要丢弃基于 的分支std::is_pointer_v<T>
,请查看constexprif
:
if constexpr (std::is_pointer_v<T>) {
// ...
} else {
// this code can be invalid if T is a pointer
}
就像是
if (std::is_pointer_v<T>)
return std::tuple_size_v<decltype(std::remove_pointer_t<T>::my_tuple)>;
else
return std::tuple_size_v<decltype(T::my_tuple)>;
一般不会工作。
在您的特定示例中,您始终可以删除指针,因为 ifT
不是指针类型,std::remove_pointer_t<T>
它T
本身就是:
template <typename T>
std::size_t f(T&&) {
using Tuple = decltype(std::remove_pointer_t<std::decay_t<T>>::my_tuple);
return std::tuple_size_v<Tuple>;
}
推荐阅读
- python - 如何使我的 python 3 桌面应用程序可移植?
- c# - 从泛型中检索字段
- css - 为什么 :nth-child() 选择不存在的孩子?
- python - 如何矢量化(利用 pandas/numpy)而不是使用嵌套的 for 循环
- powershell - Powershell在脚本中获取“-command”开关值
- xamarin - 托管 Xamarin HttpClient 实现是否支持 TLS 1.2?
- java - 编码bat字符串theEnd
- r - R:用列表填充空矩阵并保留行名和列名
- git - Gitlab:仅在创建和更新时触发合并请求的 CI Webhook
- mysql - 用更高的日期替换主日期 if, sql, mysql