std::bind有时被描述为“部分应用程序”。当函数的所有参数都被绑定时,函数本身没有被应用的原因吗?
例如,下面的代码不输出任何内容。
#include <functional>
#include <iostream>
using namespace std;
using namespace std::placeholders;
void f(int a,string b) {cout << a << b << endl;};
int main() {
bind(bind(f,1,_1),"Hi!");
return 0;
}是否有一种方法可以在所有参数固定时应用该函数的绑定变量?
-更新
我从响应中了解到,std::bind并不完全是部分应用程序。因此,在问题的第二部分,我如何编写类似于std::bind但是部分应用程序的东西。我知道bind(bind(f,1,_1),"Hi!")()将调用最后的0进制函数并返回结果值(在示例中打印1Hi )。在绑定的终端情况下,是否可以执行模板编程来调用函数调用操作符()?
换句话说,是否可以编写一个函数bind1?
template< class R, class F, class... Args >
bind1( F f, Args... args ),这样,当std::is_placeholder<T>::value == 0针对args的每个成员时,除了std::bind()的功能之外,bind1()还可以调用operator()?
发布于 2014-01-21 04:28:13
没有参数的函数只是Haskell中的一个值。你不叫它,你就用它。由于没有副作用,所以没有明显的差别。
在OCaml中,不存在没有参数的函数,要获得类似的内容,需要添加一个虚拟的单元参数。
但在C++中并非如此。C++与Haskell和OCaml不同,它在f和f()之间保持着明显的区别。bind给出了前者,因为您总是可以通过添加()将其转换为后者。您可以为bind编写自己的包装器,这样做非常容易。往相反的方向走会有点困难。
下面是这样一个包装器的可能实现:
#include <functional>
#include <utility>
#include <iostream>
template <typename T>
struct is_noargs_callable {
private:
typedef char(&yes)[1];
typedef char(&no)[2];
template<typename U>
static yes test(decltype((std::declval<U>())())*);
template<typename>
static no test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
template <typename T>
struct is_noargs_callable<T()> {
static const bool value = true;
};
template <typename T>
struct is_noargs_callable<T(...)> {
static const bool value = true;
};
template <typename T>
auto call_me_if_you_can(T t) -> typename std::enable_if<is_noargs_callable<T>::value, decltype(t())>::type
{
return t();
}
template <typename T>
auto call_me_if_you_can(T t) -> typename std::enable_if<!is_noargs_callable<T>::value, T>::type
{
return t;
}
template <typename... Args>
auto apply(Args&&... args) -> decltype(call_me_if_you_can(std::bind(args...))) {
return call_me_if_you_can(std::bind(args...));
}
// testing
void foo(int a, int b, int c) { std::cout << "foo(" << a << "," << b << "," << c << ")"; }
int main ()
{
using namespace std::placeholders;
std::cout << "zero : " ; apply(foo, _1, _2, _3); std::cout << " : " ; apply(foo, _1, _2, _3)(1,2,3); std::cout << std::endl;
std::cout << "one : " ; apply(foo, 1, _1, _2); std::cout << " : " ; apply(foo, 1, _1, _2)(2,3); std::cout << std::endl;
std::cout << "two : " ; apply(foo, 1, 2, _1); std::cout << " : " ; apply(foo, 1, 2, _1)(3); std::cout << std::endl;
std::cout << "three: " ; apply(foo, 1, 2, 3); std::cout << " : "; /* nothing to test here */ std::cout << std::endl;
}然而,仅仅在这一点上消除f和f()之间的差异并不能提高C++编程的整体一致性。如果你不喜欢这种区别,那就把它消灭在任何地方(或者干脆用你一只Haskell来做个大好事)。
发布于 2014-01-21 02:21:13
没有消息来源,只有我的意见。
之所以没有这样做,是因为没有理由去做。如果您知道该函数的所有输入,只需调用它。
如果您正在使用模板进行操作,从而导致这种情况,那么无论如何您都需要始终如一地编写所有代码。这里的特例只需要其他地方的特例。
https://stackoverflow.com/questions/21247882
复制相似问题