C++ 移动语义编译错误 C2751

标签 c++ visual-studio-2010 c++11 compiler-errors

我在 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/

相关文章:

c# - 如何在 Entity Framework 中处理空值?

c++ - C++ 字符串中的字符串游标/标记

c++ - 模板代码中的转发引用与 const 左值引用

c++ - 这个简单的 boost::spirit::qi 解析器有什么问题?

c++ - RGB 像素透明度

c++ - 任何人解释 C++ 代码行

c++ - 共享库地址空间

c++ - 应用于 2 vector 的 Eigen Rotation2D

c++ - 从串口读取 C++

c++ - iterator_category 和 decltype