【问题标题】:Visual Studio C2580 when using default keyword使用默认关键字时的 Visual Studio C2580
【发布时间】:2016-09-09 04:52:30
【问题描述】:

对于以下代码:

struct S
{
    S() = default;
    S(S const&) = default;
    S(S&&) = default;

    S& operator=(S const& other) = default;
    S& operator=(S&&) = default;

    template <typename... T>
    S(T&&... params)
    {
    }
};

int main()
{
    S s;
    return 0;
}

我收到一条错误消息:

错误 C2580 'S::S(void)':默认特殊的多个版本 不允许使用成员函数

我不明白。我认为该错误是由模板化构造函数引起的(通过将其注释掉并编译程序来验证这一点)。

【问题讨论】:

  • 我猜S(S&amp;&amp;); 应该有自定义实现。因为这是您窃取传递给它的参数的内存区域(即数据)的函数。否则它将与S(S const&amp;); 相同,同样适用于operator=
  • 一个main() 实际练习到你的编译错误点将使这个问题更加健壮。也许更新问题。
  • 您的模板化构造函数可以与您的任何默认构造函数相同,因此编译器不知道您想要做什么。它可以是默认、复制或移动构造函数。你说你希望它默认,但你也提供了一个自定义实现。
  • @xaxxon 当两个或多个构造函数匹配得一样好时,在重载决议中首选非模板
  • @PiotrSkotnicki 这似乎是一个更具体的错误。另外,这是我们所说的 VS,所以标准并不意味着太多。

标签: c++ templates c++11 visual-c++ defaulted-functions


【解决方案1】:
 template <typename... T>
    S(T&&... params)
    {
    }

T 可以是空的,给你一个默认构造函数,它可以是S&amp;&amp;,给你一个移动构造函数,或者它可以是const S &amp;,给你一个复制构造函数。

但是你只是告诉编译器你想要这些的默认版本,所以它很困惑,因为你也给了它一个明确的定义。

我会提出以下解决方案,因为它只是导致问题的默认构造函数,但此代码会使编译器崩溃:

struct S
{
    S() = default;
    S(S const&) = default;
    S(S&&) = default;

    S& operator=(S const& other) = default;
    S& operator=(S&&) = default;

    template <typename S, typename... T>
    S(S&& s, T&&... params)
    {
    }
};

int main()
{
    S s;
    return 0;
}

【讨论】:

  • 但我认为模板实例化永远不可能是正常的构造函数之一——这当然可能是一个 VC 错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多