2017-04-12 62 views
0

我有一个类有两个重载成员。一个接受一个整数,另一个接受一个参数的模板函数。演员未解决模板重载类成员

class MyClass 
{ 
    public: 
     void doSomething(int data){ std::cerr << data;} 
     template <typename T> doSomething(T &&data){ std::cerr << data;} 
}; 

我想这个功能

MyClass myobject; 
auto my_bind = std::bind(&MyClass::doSomething, &myobject, 2); 
my_bind(); 

绑定但这不会编译因为编译器不能扣除调用哪个函数。

error: no matching function for call to 'bind(unresolved overloaded function type, MyClass*, int)'

我明白我必须施放这个功能。

auto my_bind2 = std::bind(static_cast<void (MyClass::*)(int)>(&MyClass::doSomething), &myobject, 2); 

现在它编译和按预期工作。

但是如果我想将它与任何其他参数绑定来调用模板函数呢?这甚至有可能吗?我找不到语法。

这不起作用:

auto my_bind3 = std::bind(static_cast<void (MyClass::*)(std::string)>(&MyClass::doSomething), &myobject, std::string("Hello")); 

我想避免使用lambda表达式。我简化了MCVE的代码,但在实际的代码中,我应该使用成员指针。

感谢您的帮助

+0

* “我想避免使用lambda表达式。” * - 你喜欢困难的方式? – WhiZTiM

回答

1

您应该简单地提供成员函数模板的相关实例的地址:

auto my_bind3 = std::bind(&MyClass::doSomething<std::string&>, &myobject, std::string("Hello")); 
           //Note the reference here ^^ 

上述工作,因为std::bind会将它的参数,并自doSomething成员函数模板采用其参数转发参考,我们需要利用参考折叠。

虽然有点像下面的代码片段将“绑定”,

auto my_bind3 = std::bind(&MyClass::doSomething<std::string>, &myobject, std::string("Hello")); 
        //Note the absence of a reference here ^^ 

它是要失败的,当你最终调用my_bind3()

Demo


如果你可以使用lambda,使用它,因为完美forwading将在踢

auto my_bind4 = [&myobject](){ myobject.doSomething(std::string("\nHullo")); }; 
+0

那么这比我想象的要容易...所以即使函数需要引用,参数实际上是复制的吗?我不明白为什么第二个不起作用。 – dydil

+1

@dydil,['std :: bind'](http://en.cppreference.com/w/cpp/utility/functional/bind)总是**将其参数复制到它返回的对象中。当你调用返回对象的'operator(...)'时,已存**的**参数被传递给* bound *函数。请注意,'std :: bind'不会改变有界函数的语义。 (当“有界”函数是另一个“std :: bind”时,这是一个例外) – WhiZTiM

+1

第二次失败,因为这个实例化将导致一个函数像'void doSomthing(std :: string && data)'。但是当你调用“std :: bind对象”时,它会通过值传递存储的参数,它不会通过调用'std :: move(...)'将其转换为“rvalue”。这失败了,因为实例化需要一个“右值”。另一方面,第一种情况的作用是因为它会创建一个像'void doSomthing(std :: string &&& data)'这样的函数,并且通过引用合并规则,它会变成'void doSomthing(std :: string&data)'。这将很好地与'std :: bind'搭配使用 – WhiZTiM