小编Mar*_*ark的帖子

在using声明引入的fold表达式中使用运算符是否合法?

当我发现以下可编译gcc但不编译的代码时,我正在尝试在折叠表达式中使用任意函数clang

enum Enum {
    A = 3,
    B = 8,
    C = 5
};

namespace EnumMax {
    constexpr Enum operator>>=(const Enum left, const Enum right) {
        return left < right ? right : left;
    }
}

template<Enum ... enums>
constexpr Enum max() {
    using EnumMax::operator>>=;
    return (enums >>= ...);
}

constexpr Enum max_v = max<A, B, C>();
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/-LOudM

似乎clang不考虑重载运算符,而是尝试>>=在fold表达式中使用正则运算符。

但是,如果改写了fold表达式,clang则考虑重载运算符,并且可以正常编译:

constexpr Enum maxExplicit() {
    using EnumMax::operator>>=;
    return (A >>= (B …
Run Code Online (Sandbox Code Playgroud)

c++ clang fold-expression c++17

19
推荐指数
1
解决办法
184
查看次数

编译器可以将隐式声明的虚拟析构函数的实现放在单个单独的转换单元中吗?

以下代码使用编译和链接Visual Studio(2017和2019都使用/permissive-),但不使用gcc或进行编译clang

foo.h

#include <memory>

struct Base {
    virtual ~Base() = default; // (1)
};

struct Foo : public Base {
    Foo();                     // (2)
    struct Bar;
    std::unique_ptr<Bar> bar_;
};
Run Code Online (Sandbox Code Playgroud)

foo.cpp

#include "foo.h"

struct Foo::Bar {};            // (3)
Foo::Foo() = default;
Run Code Online (Sandbox Code Playgroud)

main.cpp

#include "foo.h"

int main() {
    auto foo = std::make_unique<Foo>();
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,in main.cpp中的Foo::Bar必须是完整类型,因为in中尝试将其删除~Foo(),它是隐式声明的,因此在访问它的每个翻译单元中都是隐式定义的。

但是,Visual Studio不同意,并接受此代码。此外,我发现以下更改使Visual Studio代码遭到拒绝:

  • 使(1)非虚拟
  • 定义(2)内联-即Foo() …

c++ visual-c++ language-lawyer delete-operator incomplete-type

8
推荐指数
1
解决办法
145
查看次数

当没有创建类的实例时,该标准是否允许不隐式定义隐式虚拟析构函数?

在思考这个问题时,我偶然发现了我不了解的其他内容。

标准说...

[class.dtor] / 4

如果类没有用户声明的析构函数,则将析构函数隐式声明为默认值。隐式声明的析构函数是其类的内联公共成员。

[class.dtor] / 10

[...]如果类具有带有虚拟析构函数的基类,则其析构函数(无论是用户声明的还是隐式声明的)都是虚拟的。

[class.dtor] / 7

默认使用但未定义为deleted的析构函数在使用odr时或在其首次声明后被明确默认为隐式定义。

[basic.def.odr] / 3

[...]如果虚拟成员函数不是纯函数,则将被使用。[...]

所以现在我想知道这段代码是否应该编译:

#include <memory>

struct Base {
    virtual ~Base() = default;
};

struct Bar;
struct Foo : Base {
    std::unique_ptr<Bar> bar_{};
};
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/B0wvzd

我认为~Foo()必须对其进行隐式定义,因为它是虚拟的,但由于Bar在此TU中不完整,因此无法编译。但是代码可以在所有主要的编译器中编译。

我想念什么?

c++ one-definition-rule language-lawyer implicit-declaration virtual-destructor

7
推荐指数
1
解决办法
188
查看次数