我在多个场合都看到过这个问题,它似乎出现在 Windows(visual studio)和 Linux(gcc)中。这是它的简化版本:
class noncopyable
{
public:
noncopyable(int n);
~noncopyable();
noncopyable(const noncopyable&) = delete;
noncopyable& operator=(const noncopyable&) = delete;
noncopyable(noncopyable&&);
int& setvalue();
private:
int* number;
};
class thread_starter
{
public:
template<typename callable>
bool start(callable & o);
};
template<typename callable>
inline bool thread_starter::start(callable & o)
{
std::thread t(
[&]() {
int i = 10;
while (i-- > 0)
{
noncopyable m(i);
std::thread child(o, std::move(m));
child.detach();
}
});
return true;
}
class callable
{
public:
virtual void operator()(noncopyable &m);
};
void callable::operator()(noncopyable & m) { m.setvalue()++; }
int main()
{
thread_starter ts;
callable o;
ts.start(o);
}
代码看起来足够合法,但它不会编译。
在Visual Studio中,它将给出:
error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
在GCC中,它将给出:
error: no type named ‘type’ in ‘class std::result_of<callable(int)>’....
我想我知道问题出在某种形式的复制或引用机制上,但所有语法似乎都是正确的。
我错过了什么?
我对示例进行了一些更改,对于造成的混乱,我深表歉意。我试图尽可能纯粹地重现问题,但我自己并不完全理解。