小编son*_*yao的帖子

为什么模板化的派生类可以在gcc上访问其基本私有成员?

我正在学习c ++.现在我明白派生类不能访问它的基类私有成员,但为什么一个模板化的人可以?

比如像这样的东西工作正常:

class base {
     static int x;
};
template<typename T>
class derived: public base{
    T t;
public:
    void setx(int i) {x=i;}
    int getx(){return x;}
};
Run Code Online (Sandbox Code Playgroud)

我在linux上使用gcc 5.4.

c++ inheritance gcc templates private-members

9
推荐指数
1
解决办法
156
查看次数

如何在不指定数组大小的情况下声明数组,而在C ++中的类内声明一个初始化器?

如果它具有初始化程序,则可以在不显式说明其大小的情况下声明数组:

// very fine: decltype(nums) is deduced to be int[3]
int nums[] = { 5, 4, 3 }; 
Run Code Online (Sandbox Code Playgroud)

但是,当在类中声明数组时,这是行不通的:

class dummy_class
{
    // incomplete type is not allowed (VS 2019 c++17)
    int nums[] = { 5, 4, 3 }; 
};
Run Code Online (Sandbox Code Playgroud)

为什么会这样呢?

c++ arrays language-lawyer c++17

9
推荐指数
1
解决办法
394
查看次数

隐藏用于聚合初始化的空基类

考虑以下代码:

struct A
{
    // No data members
    //...
};

template<typename T, size_t N>
struct B : A
{
    T data[N];
}
Run Code Online (Sandbox Code Playgroud)

这就是你必须如何初始化 B:B<int, 3> b = { {}, {1, 2, 3} }; 我想避免基类不必要的空 {}。Jarod42 here提出了一个解决方案,但是,它不适用于元素默认初始化:B<int, 3> b = {1, 2, 3};很好,但B<int, 3> b = {1};不是:b.data[1]并且b.data[2]没有默认初始化为 0,并且会发生编译器错误。有什么方法(或者 C++20 会有)从构造中“隐藏”基类?

c++ initialization aggregate-initialization c++20

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

函数调用中的隐式析构函数执行

我想知道关于下面这段代码的标准是什么.可以string临时对象的析构函数调用之前执行printPointer

ps VS2010编译器不会抱怨此代码并且工作正常.

void printPointer(const string* pointer)
{
    cout << *pointer << endl;
}

const string* func(const string& s1)
{
    return &s1;
}

int main()
{
    printPointer(func("Hello, World!!!"));
}
Run Code Online (Sandbox Code Playgroud)

c++ destructor temporary object-lifetime language-lawyer

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

是否在重载的运算符删除函数中隐式调用析构函数?

我有一个类Item,它定义了自己的operator new和operator delete,如下所示:

class Item
{
public:
    Item(const std::string &s):msg(s)
    {
        std::cout<<"Ctor: "<<msg<<std::endl;
    }
    static void* operator new(size_t size, int ID, const std::string &extra)
    {
        std::cout<<"My Operator New. ID/extra: "<<ID<<"/"<<extra<<std::endl;
        return ::operator new(size);
    }
    static void operator delete(void* p)
    {
        std::cout<<"My Operator Delete"<<std::endl;
        return;
    }
    ~Item()
    {
        std::cout<<"Destructor: "<<msg<<std::endl;
    }
    void Print()
    {
        std::cout<<"Item::msg: "<<msg<<std::endl;
    }
private:
    std::string msg;
};
Run Code Online (Sandbox Code Playgroud)

我使用placement new创建了这种类型的对象,然后删除如下:

int main()
{
    Item *pI=new(1,"haha")Item("AC Milan");
    std::cout<<"before delete"<<std::endl;
    delete pI;
    std::cout<<"after delete"<<std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是: …

c++ destructor delete-operator

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

从nullptr_t转换为bool:有效与否?

我用3个编译器测试了以下代码,得到了3个不同的结果:错误,警告和确定.

  • GCC(5.3):错误:从'std :: nullptr_t'到'const Thing&'的用户定义转换无效
  • Clang(3.8):警告:将nullptr常量隐式转换为'bool'
  • MSVC(14.1):没有错误,没有警告

哪个编译器正确?我知道这是指针类型和bool.之间的微不足道的转换.但那是什么std::nullptr_tbool

(最后,Clang和MSVC对代码都很好.Clang以积极的方式更加冗长.)

struct Thing
{
    Thing(bool) {}
};

void addThing(const Thing&){}

int main()
{
    addThing(nullptr); // warning or error on this line
}
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors type-conversion language-lawyer c++11

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

放置在函数参数上的要求是否也适用于初始化列表?

所以我在这里读到:https://stackoverflow.com/a/598150/2642059这是非法的:

foo(i++, i++);
Run Code Online (Sandbox Code Playgroud)

但我相信这是因为没有强制序列,我理解的是初始化列表的情况.这个法律代码也是如此吗?

const int foo[] = { i++, i++ };
Run Code Online (Sandbox Code Playgroud)

c++ arguments initializer-list language-lawyer sequencing

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

不一致的警告"从'const unsigned char'转换为'const float'需要缩小转换"

Visual C++ 2017和gcc 5.4 在此代码段中产生但不是conversion from 'const unsigned char' to 'const float' requires a narrowing conversion警告:Line BLine A

#include <iostream>

int main() {
    const unsigned char p = 13;
    const float         q = p;  // Line A

    std::cout << q << '\n';

    const unsigned char c[3] = {0, 1, 255};
    const float         f[3] = {c[2], c[0], c[1]};  // Line B

    for (auto x:f)
        std::cout << x << '\n';
}
Run Code Online (Sandbox Code Playgroud)

这个警告有效吗?为什么Line B治疗不同于Line A

c++ gcc gcc-warning visual-c++ c++11

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

为什么std :: is_rvalue_reference没有做广告要做的事情?

例如,如果我有

#include <type_traits>

struct OwnershipReceiver
{
  template <typename T,
            class = typename std::enable_if
            <
                !std::is_lvalue_reference<T>::value
            >::type
           >
  void receive_ownership(T&& t)
  {
     // taking file descriptor of t, and clear t
  }
};
Run Code Online (Sandbox Code Playgroud)

复制自如何使模板右值引用参数仅绑定到右值引用?

海报使用!std::is_lvalue_reference而不是立即更明显std::is_rvalue_reference.我已经在我自己的代码中验证了这一点,前者有效,后者没有.

任何人都可以解释为什么明显不起作用?

c++ templates enable-if c++11

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

为什么在特殊成员函数中将 r 值绑定到 const 左值引用是非法的?

对于函数参数,可以将 r 值绑定到 l 值常量引用。但是,这似乎不适用于特殊成员函数,如 C++11 和 C++14 中的复制构造函数和复制赋值运算符。这有什么动机吗?

使用 C++17 时,可以从 r 值复制构造,但不能复制赋值。是否有动机为什么这里只更改了复制构造函数的行为?

所有这些都在以下示例中进行了演示:

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

void bar(B const &) {}

int main() {
    bar(B{}); // does work
    B(B{}); // only works in C++17

    B b{};
    b = B{}; // doesn't work
}
Run Code Online (Sandbox Code Playgroud)

c++ rvalue language-lawyer c++11 c++17

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