我在 MSVS2010 中用 C++11 移动语义做了一些实验,发现了一个我无法解释的编译错误。这是重现此错误的代码:
#include <iostream>
#include <memory>
struct NonCopyable
{
protected:
NonCopyable() {}
private:
NonCopyable( const NonCopyable& );
NonCopyable& operator = ( const NonCopyable& );
};
struct A: private NonCopyable
{
template< typename T >
static std::unique_ptr< A > Create()
{
std::cout << __FUNCTION__ << std::endl;
T t = T();
return std::unique_ptr< A >( new A() );
}
};
struct B: private NonCopyable
{
B( std::unique_ptr< A >&& )
{
std::cout << __FUNCTION__ << std::endl;
}
};
struct C: private NonCopyable
{
C( B&& )
{
std::cout << __FUNCTION__<< std::endl;
}
};
int main( int argc, char* argv[] )
{
C c( B( A::Create< char >() ) );
return 0;
}
尝试编译代码时收到以下错误消息:
error C2751: 'A::Create' : the name of a function parameter cannot be qualified
但是如果我像这样更改主函数,错误就会消失:
int main( int argc, char* argv[] )
{
// I've added extra parentheses around B( A::Create< char >() )
C c( ( B( A::Create< char >() ) ) );
return 0;
}
你能解释一下这是怎么回事吗?为什么我需要额外的括号?
最佳答案
MVP ( Most vexing parse ) 就是这种情况
让我们重写 main 函数以使其更加清晰:
int main( int argc, char* argv[] )
{
typedef std::unique_ptr< A > (*Ptr)();
Ptr ptr = &A::Create< char >;
C c( B( ptr() ) );
return 0;
}
编译器何时会输出冗长的警告信息:
warning C4930: 'C c(B (__cdecl *)(void))': prototyped function not called (was a variable definition intended?)
编译器将 B( ptr() ) 视为一个正常的函数声明,就像这样:
int ( foo() )
{
return 1;
}
这就是为什么使用额外的括号有助于避免编译错误。
关于C++ 移动语义编译错误 C2751,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25332004/