小编Mic*_*ens的帖子

为什么微不足道的复制/移动可构造性取决于微不足道的可破坏性?

除了非平凡的析构函数之外,所有特殊函数都默认的类不是可简单移动或复制构造的。有关示例,请参见https://godbolt.org/z/o83rPz

#include <type_traits>

class Sample
{
public:
        Sample(Sample const&) = default;
        Sample(Sample&&) = default;
        Sample& operator=(Sample const&) = default;
        Sample& operator=(Sample&&) = default;
        ~Sample() {}
};

static_assert(std::is_copy_constructible<Sample>::value, "");
static_assert(std::is_move_constructible<Sample>::value, "");
static_assert(std::is_trivially_copy_constructible<Sample>::value, ""); // Fails with GCC and Clang
static_assert(std::is_trivially_move_constructible<Sample>::value, ""); // Fails with GCC and Clang
static_assert(std::is_copy_assignable<Sample>::value, "");
static_assert(std::is_move_assignable<Sample>::value, "");
static_assert(std::is_trivially_copy_assignable<Sample>::value, "");
static_assert(std::is_trivially_move_assignable<Sample>::value, "");
Run Code Online (Sandbox Code Playgroud)

GCC 和 Clang 都没有通过相应的断言,而 ICC 通过。奇怪的是,分配没有受到影响,尽管我可以理解分配给的对象需要被销毁。但反过来说似乎是对的。为什么?为什么ICC不同意?

c++ c++11 trivially-copyable

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

ICC拒绝模板引用成员初始化

请考虑以下示例。类模板Sample尝试使用模板参数的成员函数初始化引用成员,并期望该成员函数返回适当的引用。

class Inner
{
public:
    Inner() : x_{1}
    {
    }

private:
    int x_;
};

class Outer
{
public:
    Inner& GetInner()
    {
        return inner_;
    }

private:
    Inner inner_;
};

template<typename T>
class Sample
{
public:
    Sample(T& outer) :
        innerOk_{static_cast<Inner&>(outer.GetInner())},
        innerFail_{outer.GetInner()} // ICC fails with "error: initial value of reference to non-const must be an lvalue"
    {
    }

private:
    Inner& innerOk_;
    Inner& innerFail_;
};

int main(int argc, char* argv[])
{
    Outer outer;
    Sample<Outer> s{outer};
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,在看到的实际参数之前T,编译器无法告诉初始化是否有效,或者函数返回的类型是否不合适。因为它也无法确定是否 …

c++ templates initialization icc

6
推荐指数
0
解决办法
47
查看次数

std::optional:不参与重载决议与被定义为已删除

我试图了解类型特征传播背后的机制,如http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0602r4.html 中std::optional 所述。复制操作的处理有细微的差别,复制操作应有条件地定义为删除,而移动操作则不应参与重载决议。

这种差异的原因是什么,我将如何测试后者?例子:

#include <type_traits>
#include <optional>

struct NonMoveable {
  NonMoveable() = default;
  NonMoveable(NonMoveable const&) = default;
  NonMoveable(NonMoveable&&) = delete;
  NonMoveable& operator=(NonMoveable const&) = default;
  NonMoveable& operator=(NonMoveable&&) = delete;
};

// Inner traits as expected
static_assert(!std::is_move_constructible<NonMoveable>::value);
static_assert(!std::is_move_assignable<NonMoveable>::value);

// The wrapper is moveable, via copy operations participating in
// overload resolution. How to verify that the move operations don't?
static_assert(std::is_move_constructible<std::optional<NonMoveable>>::value);
static_assert(std::is_move_assignable<std::optional<NonMoveable>>::value);

int main(int argc, char* argv[])
{
  NonMoveable a1;
  NonMoveable a2{std::move(a1)}; // Bad, as expected
  std::optional<NonMoveable> b1;
  std::optional<NonMoveable> …
Run Code Online (Sandbox Code Playgroud)

c++ optional overload-resolution

6
推荐指数
1
解决办法
280
查看次数