相关疑难解决方法(0)

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
查看次数

为什么标准让我免费存储分配没有析构函数的类?

如果你有一个没有析构函数的类:

struct A {
    ~A() = delete;
};
Run Code Online (Sandbox Code Playgroud)

该标准不允许我"本地"分配该类的实例:

int main()
{
    A a; //error
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在免费商店分配它似乎没关系:

int main()
{
    a *p = new A();
}
Run Code Online (Sandbox Code Playgroud)

只要我不在该指针上调用delete:

int main()
{
    a *p = new A();
    delete p; //error
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,如果我在免费商店分配它,为什么标准让我有一个没有析构函数的类?我猜有一些用例吗?但到底是什么?

c++ c++11 c++14

5
推荐指数
2
解决办法
215
查看次数

如果C++函数的返回类型是T,那么返回类型T的局部变量是否有效地使变量成为rvalue?

当我用GCC编译时:

struct A
  {
    A();
    A(const A &);
    A(A &&) = delete;
  };

void ugh(A);

A bar()
  {
    A a;
    ugh(a);
    return(a);
  }
Run Code Online (Sandbox Code Playgroud)

我收到错误:

x.cpp: In function ‘A bar()’:
x.cpp:14:13: error: use of deleted function ‘A::A(A&&)’
     return(a);
             ^
x.cpp:5:5: note: declared here
     A(A &&) = delete;
     ^
Run Code Online (Sandbox Code Playgroud)

实际上,将return语句中的a视为rvalue(因为它即将被销毁)确实是有意义的.但是,标准是否要求rvalues是匿名的?

此外,即使在这种情况下允许使用移动构造函数,为什么还需要它?为什么编译器不能使用复制构造函数,因为移动构造函数不可用?

他之前的问题的答案,返回本地对象是否需要移动语义?,主要解决我的问题,但不要触及命名变量如何成为没有调用std :: move()的右值.

编辑:这两个链接解释了为什么gcc的行为是正确的,并阐明了为什么标准需要这种行为: 为什么C++ 11删除的函数参与重载解析? http://en.cppreference.com/w/cpp/language/return

c++ c++11

5
推荐指数
0
解决办法
73
查看次数

尽管 S 移动构造很好,为什么 std::is_move_constructible&lt;S&gt;::value == false ?什么是正确的行为?

以下代码S通过const &&.
然而它返回0,表明S不可移动构造!

  1. main根据标准,2 个标记结构中每一个的正确行为是什么?

  2. 如果返回0是正确的行为,其背后的原理是什么?
    (为什么它不应该反映类型实际上是否可以通过移动构造?)

#include <algorithm>

struct S
{
    S(          ) { }
    S(S        &) { }  // = delete; doesn't make any difference
    S(S const  &) { }  // = delete; doesn't make any difference
    S(S const &&) { }
    S(S       &&) = delete;
};

int main()
{
    S const s1;
    S s2(std::move(s1));  // OK for >= C++11
    S s3((S()));          // OK for >= C++17, …
Run Code Online (Sandbox Code Playgroud)

c++ move-constructor move-semantics c++11 c++17

3
推荐指数
1
解决办法
111
查看次数

在编译器生成的复制构造函数上强制模板化构造函数

采取以下,

template<class T>
struct Foo {
    Foo(){}

    // a template constructor "generalized" over related types
    template<class U>
    Foo(Foo<U> const&) {
        std::cout << 1;
    }

    // copy constructor
    Foo(Foo const&) {
        std::cout << 2;
    }
};
Run Code Online (Sandbox Code Playgroud)

及其用户:

void main() {
   Foo<int> f1;
   Foo<const int> f2(f1); // prints 1
   Foo<const int> f3(f2); // prints 2
}
Run Code Online (Sandbox Code Playgroud)

即使没有显式复制构造函数,编译器也会生成一个并使用它f3(f2).

有没有办法强制模板重载?例如,复制构造函数可以是SFINAE吗?这是为了避免代码重复,有趣的是,似乎没有办法使用委托构造函数(从复制构造函数委托给模板).

c++ templates constructor c++11

0
推荐指数
1
解决办法
49
查看次数

C++:使用auto将类声明为函数内的变量

我正在尝试对我的函数中的所有局部变量使用auto.

请使用以下代码:

class obj 
{
  public:
  obj() {};
  obj( obj&& o ) = delete;
};

int main()
{
  obj test0;
  auto test1 = obj();

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译代码:

$ g++ --std=c++1z main.cpp
main.cpp: In function ‘int main()’:
main.cpp:13:20: error: use of deleted function ‘obj::obj(obj&&)’
   auto test1 = obj();
Run Code Online (Sandbox Code Playgroud)

请注意,定义test0完全没问题,但尝试执行完全相同类型的test1声明是编译器错误.显然应该是编译器错误,但在这种情况下,是否意味着obj无法用auto定义?我正在使用我无法控制的QT对象来解决这个问题.

我还在使用C++ 98格式来声明变量,还是有其他方法可以使用auto?

谢谢!!!

c++ move-semantics c++11 c++17

0
推荐指数
1
解决办法
121
查看次数