我有可变参数模板类,表示带有函数和输入参数的线程。
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
答案 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 question,this
指针永远不是左值,因此应该有Foo*
类型(不 Foo* const
),并且应该绑定到Foo*&&
。这似乎是一个MSVC错误。
[关于使用&*this
时的GCC行为,我不知道。]
答案 1 :(得分:0)
传入的指针的常量是否阻止编译器允许转换?在你的情况下,如果你假设Foo &amp;&amp;,那么你就会收到对指针或临时指针的引用,但在任何一种情况下,它都是&#39;指针&# 39;你可以实际修改的值。在你拥有它的意义上是const的指针,不能改变指向的指针,例如,指针本身的目标被卡住。当涉及到指针时,有两个常量:一个用于指针本身,另一个用于指向的指针。他们写的&#34; const&#34;在&#34; &#34;的左侧和右侧;在变量声明中分别。