在 C++ 中是不是有一种最佳方式来运行指向该值的指针链?

Posted

技术标签:

【中文标题】在 C++ 中是不是有一种最佳方式来运行指向该值的指针链?【英文标题】:In C++ is there an optimal way to run down a pointer chain to the value?在 C++ 中是否有一种最佳方式来运行指向该值的指针链? 【发布时间】:2021-09-16 00:27:19 【问题描述】:

假设我有一个程序和一个像int finalValue = 1234; 这样的值。接下来是指向 finalValue 的指针。例如:

int *p = &finalValue;
int **p2p = &p;
int ***p2p2p = &p2p;

如果我想创建一个沿着指针链运行直到到达 finalValue (1234) 的函数,如果指针的数量和指针的数量可以改变,那么最好的方法是什么。

函数将被赋予链中的第一个指针(因此在上述情况下为p2p2p)。一般遍历看起来像p2p2p -> p2p -> p -> finalvalue

如何对链中未知数量的指针执行此操作(最少 1 个,最多 5 个)

最初的原型设计让我开始使用

foo(pointer) 
    while (typeid(pointer).name() != "int") 
        //do traversal through pointer chain
    
    return pointer; //at this point it would have the value 1234

但我不知道如何正确遍历链条,或者如何有效地检查和停止。

感谢任何帮助。

【问题讨论】:

【参考方案1】:

如果你有 c++17,你可以像这样使用递归函数:

template<typename T>
constexpr auto get_pointer_value(T v) 
    if constexpr (std::is_pointer_v<T>) 
        if (!v)  // Optional error handling if you can't trust the caller.
           throw std::invalid_argument("Pointer v cannot be null");
        
        return get_pointer_value(*v);
     else 
        return v;
    

Live example.

意图很好很清楚,这一切都应该在编译时解决。


如果您确实信任该用户,则可能值得将assert(v) 添加到constexpr if 的指针部分。

【讨论】:

我会以某种方式为 nullptr 添加一些错误处理 是递归的最好方法吗?我知道在我的特定情况下,最大指针 2 指针将是 5,因此它不会阻塞堆栈,但是如果删除了该限制,我还想使用递归吗?感谢您的帮助 @A.Karwowski 如果你有足够的指针间接导致递归堆栈溢出,那么你使用了太多的指针间接。【参考方案2】:

您可以创建 foo() 的 2 个“版本”,也就是重载。一种对对象引用进行操作,一种对指针(包括指向指针的指针)进行操作,后者在取消引用其参数后递归调用foo()

编译器会适当地链接事物:

template<typename T>
T& completely_dereference(T& v)  return v; 

template<typename T>
auto& completely_dereference(T* ptr)  return completely_dereference(*ptr); 

【讨论】:

【参考方案3】:

最简单的方法可能是使用模板和重载。我们要创建两个版本的函数,一个采用T,另一个采用T*

template <typename T>
auto reduce(T pv) 
    return pv;


template <typename T>
auto reduce(T * pv) 
    return reduce(*pv);


int main() 
    int v = 10;
    auto s = &v;
    auto ss = &s;
    auto sss = &ss;

    std::cout << reduce(v) << ' ' << reduce(s) << ' '
              << reduce(ss) << ' ' << reduce(sss) << '\n';
    return 0;


当使用非指针类型调用reduce 时,它将绑定到刚刚成为标识函数的第一个版本。当使用指针类型调用时,它将绑定到第二个版本,该版本在取消引用的值上调用 reduce

上面的输出:

10 10 10 10

【讨论】:

以上是关于在 C++ 中是不是有一种最佳方式来运行指向该值的指针链?的主要内容,如果未能解决你的问题,请参考以下文章

在 GDB 中取消引用双指针(指向值的指针)

在 Python 中,是不是有一种方便的方法来重载 C++ 中的方法? [复制]

DQL选择具有一列MAX值的每一行

在 pyspark 中显示数据框不同值的最佳方法是啥?

C++ - 为啥 boost::hash_combine 是组合散列值的最佳方式?

是否有一种更简洁的方法可以在 c++(11) 中复制具有多类型值的 unordered_map