gpt4 book ai didi

c++ - 使用模板创建默认函数参数

转载 作者:行者123 更新时间:2023-12-03 07:37:17 24 4
gpt4 key购买 nike

我正在尝试创建一种方法,用户可以在其中提供分析梯度函数(如果可用),但如果不可用,则默认使用数字梯度。

为此,我尝试了以下方法:

template<typename V, typename S, S (*Fun)(const V&)> V NumericGradient(const V& p)
{
const S e = 1.0e-6;
return {
Fun(p + V(e, 0, 0)) - Fun(p - V(e, 0, 0)) / S(2) * e,
Fun(p + V(0, e, 0)) - Fun(p - V(0, e, 0)) / S(2) * e,
Fun(p + V(0, 0, e)) - Fun(p - V(0, 0, e)) / S(2) * e,
};
}

template<typename V, typename S = decltype(V()[0])>
std::vector<V> DualContouring(
S (*DistanceFunction)(const V&),
V (*GradientFunction)(const V&) = NumericGradient<V, S, decltype(DistanceFunction)>,
const S span = S(50),
const unsigned int resolution = 100)
{
return {};
}

然而,编译器失败并显示此消息(在实例化之后):

terrain_generation.cpp
../Src/examples/TerrainGeneration/terrain_generation.cpp: In function ‘std::vector<_RealType> DualContouring(S (*)(const V&), V (*)(const V&), S, unsigned int) [with V = Eigen::Matrix<float, 3, 1>; S = float]’:
../Src/examples/TerrainGeneration/terrain_generation.cpp:362:63: error: no matches converting function ‘NumericGradient’ to type ‘class Eigen::Matrix<float, 3, 1> (*)(const class Eigen::Matrix<float, 3, 1>&)’
362 | [](const Eigen::Vector3f& v) { return v.dot(v) - 10; });
| ^
In file included from ../Src/Engine/Renderer/Renderer.hpp:24,
from ../Src/examples/TerrainGeneration/terrain_generation.cpp:32:
../Src/Engine/Geometry/DualContouring.hpp:97:56: note: candidate is: ‘template<class V, class S, S (* Fun)(const V&)> V NumericGradient(const V&)’
97 | template<typename V, typename S, S (*Fun)(const V&)> V NumericGradient(const V& p)
| ^~~~~~~~~~~~~~~
../Src/examples/TerrainGeneration/terrain_generation.cpp:362:63: note: when instantiating default argument for call to ‘std::vector<_RealType> DualContouring(S (*)(const V&), V (*)(const V&), S, unsigned int) [with V = Eigen::Matrix<float, 3, 1>; S = float]’
362 | [](const Eigen::Vector3f& v) { return v.dot(v) - 10; });
| ^
../Src/examples/TerrainGeneration/terrain_generation.cpp: In function ‘void GenerateTerrain(Gallery&)’:
../Src/examples/TerrainGeneration/terrain_generation.cpp:362:63: error: no matches converting function ‘NumericGradient’ to type ‘class Eigen::Matrix<float, 3, 1> (*)(const class Eigen::Matrix<float, 3, 1>&)’
In file included from ../Src/Engine/Renderer/Renderer.hpp:24,
from ../Src/examples/TerrainGeneration/terrain_generation.cpp:32:
../Src/Engine/Geometry/DualContouring.hpp:97:56: note: candidate is: ‘template<class V, class S, S (* Fun)(const V&)> V NumericGradient(const V&)’
97 | template<typename V, typename S, S (*Fun)(const V&)> V NumericGradient(const V& p)
| ^~~~~~~~~~~~~~~
make[1]: *** [TerrainGeneration.make:156: obj/Debug/TerrainGeneration/terrain_generation.o] Error 1
make: *** [Makefile:39: TerrainGeneration] Error 2
make: Leaving directory '/home/makogan/vkengine/Generated'
Traceback (most recent call last):
File "build.py", line 139, in <module>
main()
File "build.py", line 106, in main
raise Exception("Compilation failed.")
Exception: Compilation failed.

我不确定那里的类型定义有什么问题。 NumericGradient 的实例化应该与预期的功能类型兼容。

这就是我尝试调用 stub 的方式:

auto contour = DualContouring<Eigen::Vector3f, float>(
[](const Eigen::Vector3f& v) { return v.dot(v) - 10; });

我在 linux 下用 g++ 9.3 编译。

替代问题

好的,我尝试完全删除默认参数并强制用户始终传递函数指针。

不知何故甚至这样:

    float (*Distance)(const Eigen::Vector3f&) = [](const Eigen::Vector3f& v) {
return v.dot(v) - 9;
};
auto contour = DualContouring<Eigen::Vector3f, float>(
Distance, NumericGradient<Eigen::Vector3f, float>, Distance);

编译失败:

error: no matches converting function ‘NumericGradient’ to type ‘class Eigen::Matrix<float, 3, 1> (*)(const class Eigen::Matrix<float, 3, 1>&)’
365 | Distance, NumericGradient<Eigen::Vector3f, float>, Distance);```

Why? The template declaration should be fine.

最佳答案

正在关注 Jarod42 explanation , NumericGradient 的第三个模板参数是一个非类型参数,而 decltype(DistanceFunction) 是一个类型。所以,我相信你想做的是使用 DistanceFunction,但是,正如他提到的,不能在这种情况下使用参数名称。

作为替代方案,您可以将函数指针模板参数“降级”为常规函数指针参数:

template<typename V, typename S> V NumericGradient(const V& p, S (*Fun)(const V&));

并传递它。

这是一个工作示例: https://godbolt.org/z/qhY938

作为另一种选择,您可以将 DistanceFunction 作为模板参数传递给 DualContouring

这是另一个工作示例: https://godbolt.org/z/EnaMjK

关于c++ - 使用模板创建默认函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65497659/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com