You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免取标准库函数地址时的非标准行为?

解决取标准库函数地址的未定义行为问题

标准库中大部分函数(比如std::sqrt)的地址不能直接获取,这属于未定义行为——因为标准允许实现对这些函数提供重载、inline特化或者其他优化,直接取地址可能导致编译或运行时的意外问题。针对你的代码,有两种简单的修正方案:

方案一:用自定义包装函数封装标准库函数

自己写一个简单的包装函数,内部调用标准库函数,然后取这个自定义函数的地址即可:

#include <iostream>
#include <vector>
#include <cmath>

bool divisible_3(double n){
    return static_cast<int>(n) % 3 == 0;
}

// 包装std::sqrt的自定义函数
double sqrt_wrap(double x) {
    return std::sqrt(x);
}

void applyFunction(std::vector<double>& vector, bool(* filterf)(double), double(*calc)(double)){
    for(size_t index = 0; index < vector.size(); index++){ // 用size_t替代int更规范
        if(filterf(vector[index])){
            vector[index] = calc(vector[index]);
        }
    }
}

int main(){
    std::vector<double> vect = {1, 2, 3, 5, 9, 16, 21, 24};
    applyFunction(vect, divisible_3, sqrt_wrap); // 传自定义包装函数的地址
    
    for(auto&& i: vect){
        std::cout << i << std::endl;
    }
}

方案二:将applyFunction改为模板函数,支持任意可调用对象

这种方式更灵活,不需要依赖函数指针,直接传递lambda、仿函数等可调用对象,同时避免取标准库函数地址的问题:

#include <iostream>
#include <vector>
#include <cmath>

bool divisible_3(double n){
    return static_cast<int>(n) % 3 == 0;
}

// 模板版本的applyFunction,接受任意可调用对象
template<typename FilterFunc, typename CalcFunc>
void applyFunction(std::vector<double>& vector, FilterFunc filterf, CalcFunc calc) {
    for(size_t index = 0; index < vector.size(); index++){
        if(filterf(vector[index])){
            vector[index] = calc(vector[index]);
        }
    }
}

int main(){
    std::vector<double> vect = {1, 2, 3, 5, 9, 16, 21, 24};
    // 用lambda封装std::sqrt,直接传递lambda即可
    applyFunction(vect, divisible_3, [](double x) { return std::sqrt(x); });
    
    for(auto&& i: vect){
        std::cout << i << std::endl;
    }
}

两种方案都能解决问题,方案二更符合现代C++的风格,扩展性更强,建议优先使用。

内容的提问来源于stack exchange,提问作者JosephGen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 12:57:58