admin管理员组

文章数量:1292298

We have remove_pointer that works for types:

static_assert(std::is_same_v<int, std::remove_pointer_t<int>> == true);
static_assert(std::is_same_v<int, std::remove_pointer_t<int*>> == true);

Is there an equivalent existing for objects? Something like:

int x = 1;
int* py = new int(2);
int& rx = remove_pointer_object<int>(x);
int& ry = remove_pointer_object<int*>(py);

I am using references to avoid copies, but if you have suggestions that work with values, don't hesitate.


NB This can probably be implemented like so:

template<typename T> T& remove_pointer_object(T& x) { return x; }
template<> T& remove_pointer_object<T*>(T* x) { return *x; }

But is there something already existing?


For context, I'm working on the following usecase:

template<typename I>
ReturnType my_function(I iterable) {
  // some pre-processing
  for (auto const& element : iterable) {
    // process element
    // element can be a plain object
    // element can be a pointer
  }
  // some post-processing
}

We have remove_pointer that works for types:

static_assert(std::is_same_v<int, std::remove_pointer_t<int>> == true);
static_assert(std::is_same_v<int, std::remove_pointer_t<int*>> == true);

Is there an equivalent existing for objects? Something like:

int x = 1;
int* py = new int(2);
int& rx = remove_pointer_object<int>(x);
int& ry = remove_pointer_object<int*>(py);

I am using references to avoid copies, but if you have suggestions that work with values, don't hesitate.


NB This can probably be implemented like so:

template<typename T> T& remove_pointer_object(T& x) { return x; }
template<> T& remove_pointer_object<T*>(T* x) { return *x; }

But is there something already existing?


For context, I'm working on the following usecase:

template<typename I>
ReturnType my_function(I iterable) {
  // some pre-processing
  for (auto const& element : iterable) {
    // process element
    // element can be a plain object
    // element can be a pointer
  }
  // some post-processing
}
Share Improve this question edited Feb 13 at 13:52 R2B2 asked Feb 13 at 11:12 R2B2R2B2 1,5972 gold badges12 silver badges19 bronze badges 8
  • What problem are you trying to solve? If you have int* p and a function f(int& x) just call it with f(*p) – Pepijn Kramer Commented Feb 13 at 11:17
  • 1 int* py = 2; that's an error. There's no point in equal treatment of references and pointers. For pointers you can always use the dereference operaotor: *py. – Red.Wave Commented Feb 13 at 11:17
  • There isn't any such function in standard, because you either don't care about type at all (e.g., passing it along) or you already need to know if it's an object or a pointer (at least in duck-typing manner). What you proposed is just the tip of an iceberg - what about smart pointers? Do you also want to dereference iterators? Do you want to call unary operator* on every class that has it overloaded (regardless of what it my actually do)? – Yksisarvinen Commented Feb 13 at 11:22
  • 3 Add this context to the question, not in the comments, please. – j6t Commented Feb 13 at 12:11
  • 1 I assume int& ry = remove_pointer_object<int*>(x) was meant to be int& ry = remove_pointer_object<int*>(y)? – Alan Birtles Commented Feb 13 at 13:17
 |  Show 3 more comments

1 Answer 1

Reset to default 1

To assign (dereferenced) value dynamically, probably playing with typeid operator needed to detect ptr and assign original/dereferenced value to a variable;

Compile-time version of what is being asked. Built with C++23. T::value_type will capture only STL containers and might not be all-consuming, browse for other ways of container (iterator) content type detection.

#include <iostream>
#include <string>
#include <vector>

template<class T>
void Iterate(T container)
{
    // Option 1:
    if constexpr (std::is_pointer_v<typename T::value_type>) {
        for (const auto* element : container) { std::cout << *element << " "; }
    }
    else if constexpr (!std::is_pointer_v<typename T::value_type>) {
        for (const auto& element : container) { std::cout << element << " "; }
    }
    else { static_assert(false, "element is something else"); }

    // Option 2:
    for (const auto& element : container) {
        if constexpr      ( std::is_pointer_v<std::decay_t<decltype(element)>>) { std::cout << *element << " "; }
        else if constexpr (!std::is_pointer_v<std::decay_t<decltype(element)>>) { std::cout <<  element << " "; }
        else { static_assert(false, "element is something else"); }
    }
}

int main()
{
    std::string        s{"abc"};
    std::vector<char*> v{ s.data(), s.data()+1, s.data()+2 };
    Iterate(s);
    Iterate(v);
    std::cout << '\n';
    v.clear();
}
!ptr: a b c a b c  | ptr: a b c a b c  |

本文标签: templatesIs there a removepointer function for objects (rather than types) in standard CStack Overflow