"= default"是否允许外线实现?

Jam*_*son 6 c++ c++11

通常我会看到= default标题中使用的语法.我的理解是,这与在标题中明确实现函数的情况相同,见Foo下文.

foo.h中

#pragma once

class Foo
{
public:
    Foo() = default;

    Foo(const Foo& other) = default;
};
Run Code Online (Sandbox Code Playgroud)

纯粹出于好奇,可以= default在源文件中使用如下吗?

Bar.h

#pragma once

class Bar
{
public:
    Bar();

    Bar(const Bar& other);
};
Run Code Online (Sandbox Code Playgroud)

Bar.cpp

#include "Bar.h"

Bar::Bar() = default;

Bar::Bar(const Bar&) = default;
Run Code Online (Sandbox Code Playgroud)

据我所知,这相当于在cpp文件中显式实现这些功能.

上面的Bar例子编译gcc-5.1但是标准是否允许这种用法?

顺便说一下,= default在源文件和标题中使用是否有任何好处?

Nat*_*ica 5

是的,这是合法的。来自[dcl.fct.def.default]

显式默认函数和隐式声明函数统称为默认函数,实现应为它们提供隐式定义(12.1 12.4、12.8),这可能意味着将它们定义为已删除。如果函数是用户声明的并且在第一次声明时未显式默认或删除,则该函数是用户提供的。用户提供的显式默认函数(即,在第一次声明后显式默认)是在显式默认的位置定义的;如果这样的函数被隐式定义为已删除,则该程序是错误的。

强调我的

然后他们继续向您详细介绍具体的场景

struct nontrivial1 {
  nontrivial1();
};
nontrivial1::nontrivial1() = default; // not first declaration
Run Code Online (Sandbox Code Playgroud)

因此,只要函数没有隐式标记为已删除,那么该函数就会在您显式默认的位置定义。

= default顺便说一句,与标头相比,在源文件中使用有什么好处吗?

我能看到的唯一“优点”是它允许现有代码库更改其 cpp 文件以使用现代技术,而无需更改头文件。标准中甚至有一条注释:

注意:在首次声明后将函数声明为默认函数可以提供高效的执行和简洁的定义,同时为不断发展的代码库提供稳定的二进制接口。