Is there a way to determine whether an object has at least one of its members on the heap?
I am trying to be able to distinguish objects like std::string
or std::vector
or std::list
(yeah mostly containers) from all other types (unfortunately even containers with a single element are within my "scope of interest")
I am trying to do something like the following:
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;
};
classes foo
and bar
are just examples, and the function func()
has to perform functionality a bit different than cout
ing to console.
This is XY problem... I am trying to write a hash function that will be aware whether the user-defined key type stores any data on an array (just like std::string` would). I am fairly able to create a generic hash function that takes any type, but if that type has an array (a pointer) to some of it's stored data, problems become very tricky (pointers to dynamic arrays change at runtime, the same key at, different times will produce different hash value)
Be aware that some structure/class types have internal uninitialized padding, which may make your hash function work incorrectly.
Otherwise, std::is_trivially_copyable
would be a good start.
As others pointed out in the comments, there is no way to distinguish whether the pointer pointing to dynamically allocated or not. On the other hand, C++ standard <type_traits>
provides type traits like
and so on. Have a look at to the links, whether it suits your actual problem.
That being said, why it can't be solved with a member function which tells the information what you need?
For example:
struct foo
{
public:
bool isHeapAllocated() const noexcept { return true; }
};
struct bar
{
public:
bool isHeapAllocated() const noexcept { return false; }
};
Then simply call the function:
template <typename T> void func(T val)
{
if constexpr (std::is_class_v<T>)
{
if (val.isHeapAllocated()) {
// Do something #1.
}
else
{
// Do something #2.
}
}
else
{
// Do something #3.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With