C ++ 11:无法转换来自' T * const'到'&&'

时间:2015-09-04 21:59:37

标签: c++ c++11 variadic-templates

我有可变参数模板类,表示带有函数和输入参数的线程。

template<typename F> class my_thread;

template<typename Return, typename... Input>
class my_thread<Return(Input...)>
{
    template<typename F>
    my_thread(F&& f, Input&&... value) : /* mainly std::forward<Input>... to std::tuple<Input...> */ { }
}

现在,实例化该类对全局函数来说很简单

int fnc(int, double);
my_thread<int(int, double)> thr(fnc, 42, 3.14);

对某些类的函数成员来说(显然)并不那么简单。

my_thread<int(int, double)> thr(&Foo::fnc, 42, 3.14); // won't work, unless Foo::fnc is static.

我知道,std::thread有一些机制(可能是部分特化),它允许传递非静态成员函数,如果在所有参数之前传递指向该类实例的指针({{ 1}})。我无法找到如何实现这一点,因此我的std::thread(&Foo::bar, Foo(), 42, 3.14); // OK需要传递静态成员函数,并且指向该类实例的指针必须是该函数的激活参数。

my_thread

这是我必须忍受的,但这不是问题 问题是使用该函数实例化struct Dog { void bark(); static void bark(Dog* dog) { dog->bark(); } } 。我在Visual Studio 2015中写了my_thread并抱怨

  

错误C2664:&#39; my_thread&lt; int(Foo *,double)&gt; :: my_thread(my_thread&lt; int(Foo *,double)&gt;&amp;&amp;)&#39;:无法转换参数2来自&#39; Foo * const&#39;到&#39; Foo *&amp;&amp;&#39;

我尝试了一些施法的魔法,但后来我发现,传递my_thread<int(Foo*, double)> thr(&Foo::bar, this, 3.14);而不是&*this有效。

我很高兴找到解决方案(或至少在Windows上编译和运行的东西),我决定在Linux上使用G ++进行尝试。我使用相同的代码(使用this),但G ++对我很生气,因为

  

在成员函数&#39; void Foo :: SomeFunction()&#39;:     错误:没有匹配函数来调用'my_thread&lt; int(Foo *,     double)&gt; :: my_thread(int(*)(Foo *,double),Foo * const,double&amp;)'
   注意:候选人是:my_thread(F&amp;&amp;,Input&amp;&amp; ...)
   注意:模板参数扣除/替换失败:
  注意:无法将'this'(类型'Foo * const')转换为'Foo *&amp;&amp;'

我很惊讶我得到了和以前一样的错误。我将&*this编辑回&*this,我能够在Linux下编译并在G ++上运行它。

我的问题是:
谁是对的? G ++ 4.9.2或MVS2015?我如何解决它,以便我的代码可以在两个平台上运行? 或者,我使用不好的方法吗?如何实现std :: thread,以便它知道,当传递非静态成员函数时,它需要指向该类实例的指针作为参数吗?

修改
我正在添加更多代码,以便我的意图更清晰。

this

2 个答案:

答案 0 :(得分:3)

下面:

template<typename F>
my_thread(F&& f, Input&&... value)

您没有推断&#34;通用引用&#34;,但rvalue引用Input...参数(这是您想要的吗?)。在这里,使用Input = Foo*, double,您的构造函数读取

template<typename F>
my_thread(F&& f, Foo*&& value1, double&& value2)

这解释了Foo*&&部分。现在,根据this questionthis指针永远不是左值,因此应该有Foo*类型( Foo* const),并且应该绑定到Foo*&&。这似乎是一个MSVC错误。

[关于使用&*this时的GCC行为,我不知道。]

答案 1 :(得分:0)

传入的指针的常量是否阻止编译器允许转换?在你的情况下,如果你假设Foo &amp;&amp;,那么你就会收到对指针或临时指针的引用,但在任何一种情况下,它都是&#39;指针&# 39;你可以实际修改的值。在你拥有它的意义上是const的指针,不能改变指向的指针,例如,指针本身的目标被卡住。当涉及到指针时,有两个常量:一个用于指针本身,另一个用于指向的指针。他们写的&#34; const&#34;在&#34; &#34;的左侧和右侧;在变量声明中分别。