gpt4 book ai didi

c++ - 常量和非常量仿函数

转载 作者:可可西里 更新时间:2023-11-01 18:37:50 24 4
gpt4 key购买 nike

这似乎是应该经常问和回答的问题,但我的搜索失败了。

我正在编写一个函数,我想接受某种通用的可调用对象(包括裸函数、手动仿函数对象、bindstd::function),然后在算法的深度(即 lambda)中调用它。

函数当前声明如下:

template<typename T, typename F>
size_t do_something(const T& a, const F& f)
{
T internal_value(a);
// do some complicated things
// loop {
// loop {
f(static_cast<const T&>(internal_value), other_stuff);
// do some more things
// }
// }
return 42;
}

我通过引用接受仿函数,因为我想保证它不会在进入函数时被复制,因此实际上调用了对象的同一个实例。它是一个 const 引用,因为这是接受临时对象的唯一方法(这在使用手动仿函数或 bind 时很常见)。

但这需要仿函数将 operator() 实现为常量。我不想这样要求;我希望它能够接受两者。

我知道我可以声明此方法的两个拷贝,一个将其接受为常量,一个将其接受为非常量,以便涵盖这两种情况。但我不想这样做,因为评论隐藏了很多我不想复制的代码(包括一些循环结构,所以我不能在不移动问题的情况下将它们提取到辅助方法) .

我也知道我可能会在调用它之前作弊并将仿函数 const_cast 转换为非常量,但这感觉有潜在的危险(特别是如果仿函数有意实现两者,会调用错误的方法const 和非常量调用运算符)。

我考虑过将仿函数作为 std::function/boost::function 来接受,但这感觉像是一个本应简单的解决方案问题。 (特别是在仿函数应该什么都不做的情况下。)

除了复制算法之外,是否有满足这些要求的“正确”方法?

[注意:我更喜欢不需要 C++11 的解决方案,尽管我对 C++11 的答案也很感兴趣,因为我在两种语言的项目中使用了类似的结构。]

最佳答案

您是否尝试过转发层来强制推断限定符?让编译器通过正常的模板实例化机制进行算法复制。

template<typename T, typename F>
size_t do_something_impl(const T& a, F& f)
{
T internal_value(a);
const T& c_iv = interval_value;
// do some complicated things
// loop {
// loop {
f(c_iv, other_stuff);
// do some more things
// }
// }
return 42;
}

template<typename T, typename F>
size_t do_something(const T& a, F& f)
{
return do_something_impl<T,F>(a, f);
}

template<typename T, typename F>
size_t do_something(const T& a, const F& f)
{
return do_something_impl<T,const F>(a, f);
}

演示:http://ideone.com/owj6oB

包装器应该是完全内联的并且完全没有运行时成本,除了你可能最终会得到更多的模板实例化(因此代码量更大)之外的事实,尽管这只会发生在没有 operator()() const 的类型时,其中const(或临时)和非常量仿函数都通过了。

关于c++ - 常量和非常量仿函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20533661/

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