小编Bar*_*ett的帖子

集成初始化的C++ 17扩展是否使得大括号初始化变得危险?

似乎普遍认为,大括号初始化应优先于其他形式的初始化,但是由于将C++ 17 扩展引入聚合初始化,似乎存在意外转换的风险.请考虑以下代码:

struct B { int i; };
struct D : B { char j; };
struct E : B { float k; };

void f( const D& d )
{
  E e1 = d;   // error C2440: 'initializing': cannot convert from 'D' to 'E'
  E e2( d );  // error C2440: 'initializing': cannot convert from 'D' to 'E'
  E e3{ d };  // OK in C++17 ???
}

struct F
{
  F( D d ) …
Run Code Online (Sandbox Code Playgroud)

c++ initialization list-initialization c++17

48
推荐指数
2
解决办法
3893
查看次数

从C++中的私有模板类继承构造函数

为什么类D编译,但类C没有?

class A
{
    public:
        A(int) {}
};

template <class T>
class B : private T // Note: private base class
{
    public:
       using T::T;
};

class C : public B<A>
{
    public:
        C() : B<A>(123) {}  // Error: 'class A A::A' is inaccessible
};                          //         within this context

using BA = B<A>;

class D : public BA
{
    public:
        D() : BA(123) {}  // OK
};
Run Code Online (Sandbox Code Playgroud)

我用GCC,Clang和Visual C++ 进行了测试,它们都是一样的.改变class B : private …

c++ templates language-lawyer

46
推荐指数
1
解决办法
921
查看次数

unique_ptr什么时候需要完整的类型?

在下面的代码中,函数f()可以调用operator bool()和不完整的operator *()成员函数.但是当函数试图调用那些相同的成员函数时,编译器突然想要一个完整的类型并尝试实例化,然后失败.由于某种原因,不会导致模板实例化并正确编译,如功能中所示.这是为什么?有什么不同和?unique_ptr<C>class Cg()unique_ptr<X<C>>X<C>unique_ptr<X<C>>::get()h()get()operator bool()operator *()

#include <memory>

class C;
std::unique_ptr<C> pC;

C& f() {
    if ( !pC ) throw 0; // OK, even though C is incomplete
    return *pC;         // OK, even though C is incomplete
}

template <class T>
class X
{
    T t;
};

std::unique_ptr<X<C>> pX;

X<C>& g() {
    if ( !pX ) throw 0; // Error: 'X<C>::t' uses undefined class …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

10
推荐指数
2
解决办法
468
查看次数

无法将"成员指针指向派生类"转换为"指向基类的成员指针"

使用指向基类的指针调用类的虚拟成员函数当然是在C++中非常常见的事情.所以我觉得很奇怪,当你有一个成员指针而不是普通的指针时,似乎不可能做同样的事情.请考虑以下代码:

struct B
{
    virtual void f();
};

struct D : B
{
    virtual void f();
};

struct E
{
    B b;
    D d;
};

int main()
{
    E e;

    // First with normal pointers:
    B* pb1 = &e.b;  // OK
    B* pb2 = &e.d;  // OK, B is a base of D
    pb1->f();  // OK, calls B::f()
    pb2->f();  // OK, calls D::f()

    // Now with member pointers:
    B E::* pmb1 = &E::b;  // OK
    B E::* pmb2 = &E::d; …
Run Code Online (Sandbox Code Playgroud)

c++

9
推荐指数
2
解决办法
975
查看次数

C++ STL容器和就地构造

请考虑以下事项:

class CMyClass
{
public:
  CMyClass()
  {
    printf( "Constructor\n" );
  }
  CMyClass( const CMyClass& )
  {
    printf( "Copy constructor\n" );
  }
};

int main()
{
  std::list<CMyClass> listMyClass;

  listMyClass.resize( 1 );

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

它产生以下输出:

构造函数

复制构造函数

现在我的问题是:我如何避免复制构造函数?或者换一种方式:如何在没有不必要的复制操作的情况下在STL容器内创建对象.有没有办法使用默认构造函数进行"就地"构造?


更新 - 答案到目前为止:

  1. 它无法完成
  2. 请改用指针或智能指针.

智能指针对我的应用来说太过分了.但我真的很想知道为什么不能这样做.这似乎是一件显而易见的事情.还有其他想法吗?如果它有效,我甚至会接受一个讨厌的黑客......


我想我刚从这里提出的所有评论和答案中找到了我的问题的解决方案.解决方案是构造一个空对象并将其保留,以便以后使用它来制作干净的副本.然后,您可以使用其中一个引用方法(如push_back或insert).这仍然为每个插入的新对象调用复制构造函数,但至少它不是默认构造函数和复制构造函数:

int main()
{
  CMyClass Empty;

  std::list<CMyClass> listMyClass;

  for ( int c=0; c<10; ++c )
  {
    listMyClass.push_back( Empty );
  }

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

c++ stl

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

使用final类说明符时,最终函数说明符是多余的吗?

是否有任何理由指定一个函数,因为final该类已经final?或者这是多余的?

class B
{
public:
    virtual void f();
};

class D final : public B
{
public:
    virtual void f() final; // Redundant final?
};
Run Code Online (Sandbox Code Playgroud)

说一下这是一个很好的经验法则:从创建整个类开始final,只有final在需要派生类和/或覆盖特定函数时才切换到创建单独的函数?

c++ c++11

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

C++使用嵌套函数调用命名返回值优化

我知道NRVO允许函数构造一个对象并按值返回该对象而不需要复制或甚至移动操作的成本.它发现它也适用于嵌套函数调用,允许您从另一个函数调用的返回值构造对象.

请考虑以下程序及其输出,如注释中所示:(
Visual Studio 2017的输出,版本15.2,发布版本.)

#include <stdio.h>
class W
{
public:
  W() { printf( "W::W()\n" ); }
  W( const W& ) { printf( "W::W( const W& )\n" ); }
  W( W&& ) { printf( "W::W( W&& )\n" ); }
  W& operator=( const W& ) { printf( "W::operator=( const W& )\n" ); }
  W& operator=( W&& ) { printf( "W::operator=( W&& )\n" ); }
  ~W() { printf( "W::~W()\n" ); }
  void Transform() { printf( "W::Transform()\n" ); }
  void Run() { printf( …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

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

访问从成员函数返回的私有嵌套类

请帮助我理解为什么类成员函数可以返回私有嵌套类对象,以及为什么可以在该私有嵌套类上调用成员函数,例如:

class Y
{
    class X
    {
    public:
        void f() { cout << "Hello World" << endl; }
    };

public:
    X g() { return X(); }
};

void h()
{
    Y::X x;     // Error, as expected: class Y::X is private.
    x.f();      // Error.

    Y y;        // OK.
    y.g().f();  // OK. But why???
}
Run Code Online (Sandbox Code Playgroud)

我使用GCC和Visual C++进行了测试,最后一行编译在两者上.我似乎无法在C++标准中找到任何可以使其有效的内容.任何想法为何有效?

编辑:

另一个观察:

void i()
{
    Y y;

    Y::X x2 = y.g(); // Error: class Y::X is private
    x2.f();          // Error

    auto x3 = y.g(); // …
Run Code Online (Sandbox Code Playgroud)

c++

5
推荐指数
1
解决办法
149
查看次数

为什么不能使用宏来使用C++ 11大括号初始化?

我刚刚发现,在将参数传递给宏时,不能总是使用大括号初始化.当ASSERT()宏无法编译时,我发现了这一点.但是,以下示例说明了此问题:

#include <iostream>
#include <string>
using namespace std;

#define PRINT_SIZE( f ) cout << "Size=" << (f).size() << endl;

int main()
{
  PRINT_SIZE( string("ABC") );  // OK, prints: "Size=3"
  PRINT_SIZE( string{"ABC"} );  // OK, prints: "Size=3"

  PRINT_SIZE( string("ABCDEF",3) ); // OK, prints: "Size=3"
  PRINT_SIZE( string{"ABCDEF",3} ); // Error: macro 'PRINT_SIZE' passed 2 arguments, but takes just 1

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

有没有理由不能使大括号初始化使用宏?

编辑:

我后来发现你也可以使用一个可变参数宏,这完全解决了这个问题:

#include <iostream>
#include <string>
using namespace std;

#define PRINT_SIZE( ... ) cout << "Size=" << (__VA_ARGS__).size() << …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

4
推荐指数
2
解决办法
1553
查看次数