【发布时间】:2019-06-30 10:20:06
【问题描述】:
有没有办法确定一个对象是否至少有一个成员在堆上?
我试图能够将像 std::string 或 std::vector 或 std::list (是的,主要是容器)之类的对象与所有其他类型区分开来(不幸的是,即使具有单个元素的容器也在我的“兴趣范围”之内)
我正在尝试执行以下操作:
struct foo
{
private:
int * _ptr;
public:
foo() : _ptr(new int) {};
~foo() { delete _ptr; };
};
struct bar
{
private:
int val;
};
template <typename T>
void func(T val)
{
if constexpr (std::is_class_v<T>)
{
std::cout << std::setw(20) << typeid(T).name() << " is a class type." << std::endl;
if (/* determine if foo has any heap allocations */)
{
// Do something #1.
std::cout << std::setw(20) << typeid(T).name() << " does allocate on heap." << std::endl;
}
else
{
// Do something #2.
std::cout << std::setw(20) << typeid(T).name() << " does NOT allocate on heap." << std::endl;
}
}
else
{
// Do something #3.
std::cout << std::setw(20) << typeid(T).name() << " is NOT a class type." << std::endl;
}
}
int main()
{
func(foo()); // foo does allocate on heap
cout << endl;
func(bar()); // bar does NOT allocate on heap
cout << endl;
};
类foo 和bar 只是示例,函数func() 必须执行与cout 控制台不同的功能。
【问题讨论】:
-
如果指针是动态分配的或本地分配的,您通常无法区分它们。如果你需要这样做,那显然是 ypu 存在严重设计缺陷的迹象。
-
这看起来像是一个 XY 问题,因为一旦创建了一个对象,动态分配的对象(您错误地称为“堆分配”)和任何其他对象之间的唯一区别就是它的生命周期结束 - 假设没有未定义的行为。没有办法检测任意对象是否是动态分配的,除非以某种方式显式跟踪。如果您提出的问题实际上是可能的,您如何解释您实际期望能够实现的目标?
-
@πάνταῥεῖ 我不想区分堆栈数组和堆数组。我试图区分“
class type with an array as a member”和“class type without an array as a member”。数组是否在堆上的堆栈对我来说没有区别。我只想获取该数组中的数据。 -
@Peter 这是 XY 问题...我正在尝试编写一个哈希函数,它会知道用户定义的键类型是否在数组上存储任何数据(就像
std::string一样) .我相当能够创建一个采用任何类型的通用散列函数,但是如果该类型有一个指向其中一些存储数据的数组(指针),问题就会变得非常棘手(指向动态数组的指针在运行时发生变化,相同的键在,不同的时间会产生不同的hash值) -
@cukier9a7b5 - 如果您的哈希取决于指针的值 - 与这些指针指向的值不同 - 那么它可能没有多大用处。
std::string的值不取决于存储数据的地址 - 它取决于每个字符的值。
标签: c++ class templates c++17 member