小编gha*_*.st的帖子

方便的C++ struct初始化

我正在尝试找到一种方便的方法来初始化'pod'C++结构.现在,考虑以下结构:

struct FooBar {
  int foo;
  float bar;
};
// just to make all examples work in C and C++:
typedef struct FooBar FooBar;
Run Code Online (Sandbox Code Playgroud)

如果我想在C(!)中方便地初始化它,我可以简单地写:

/* A */ FooBar fb = { .foo = 12, .bar = 3.4 }; // illegal C++, legal C
Run Code Online (Sandbox Code Playgroud)

请注意,我想明确地避免使用以下表示法,因为如果我将来更改结构中的任何内容,它会让我感到沮丧:

/* B */ FooBar fb = { 12, 3.4 }; // legal C++, legal C, bad style?
Run Code Online (Sandbox Code Playgroud)

为了实现与/* A */示例中相同(或至少类似)的C++ ,我将不得不实现一个愚蠢的构造函数:

FooBar::FooBar(int foo, float bar) : foo(foo), bar(bar) {}
// -> …
Run Code Online (Sandbox Code Playgroud)

c++ struct initialization

137
推荐指数
6
解决办法
11万
查看次数

是否可以将std :: numeric_limits <T>专门用于用户定义的类似数字的类?

文档std::numeric_limits<T>说它不应该专门针对非基本类型.数字式用户定义类型怎么样?如果我定义了我自己的T表示数值的类型并重载数字运算符,并且表示的信息numeric_limits是有意义的 - 如果我专门numeric_limits针对该类型,会有什么破坏吗?

c++ standards types numbers

24
推荐指数
2
解决办法
4363
查看次数

全局operator new和malloc之间的区别

C++有几个功能来获取动态存储,其中大部分功能在某些基本方面有所不同.OS通常会添加几个.

由于它们的便携性和相似性,其中两个特别感兴趣:malloc::operator new.

全局void* operator new(size_t, ::std::nothrow&)void* malloc(size_t)?之间是否有任何差异(标准和实施)?

由于我所说的似乎有些混乱,请考虑以下两个调用:

void* p = ::std::malloc(10);
void* q = ::operator new(10, ::std::nothrow);
Run Code Online (Sandbox Code Playgroud)

明显和微不足道的区别在于如何释放内存:

::std::free(p);
::operator delete(q);
Run Code Online (Sandbox Code Playgroud)

注意:这个问题不重复,例如new/delete和malloc/free有什么区别?因为它谈到使用实际上不执行任何ctor调用的全局 operator new.

c++ malloc memory-management new-operator c++11

23
推荐指数
2
解决办法
1851
查看次数

构造函数继承的虚拟继承

我有一个类层次结构,归结为

class Module { };

struct Port {
    Module& owner;
    Port(Module& owner) : owner(owner) {}
};

struct InPort    : virtual Port    { using Port::Port; };
struct OutPort   : virtual Port    { using Port::Port; };
struct InOutPort : InPort, OutPort { using Port::Port; };
Run Code Online (Sandbox Code Playgroud)

如您所见,我更愿意创建一些基本功能,并以经典的菱形图案继承它.我也想使用构造函数继承使其尽可能地证明未来...

但是,这不起作用如上所述

prog.cpp: In function 'int main()':
prog.cpp:14:15: error: use of deleted function 'InOutPort::InOutPort(Module&)'
  InOutPort p(m);
Run Code Online (Sandbox Code Playgroud)

InOutPort使用更明确的版本替换定义也是不够的:

struct InOutPort : InPort, OutPort { InOutPort(Module& m) : Port(m), InPort(m), OutPort(m) { } }; …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance virtual-inheritance c++11

14
推荐指数
1
解决办法
311
查看次数

什么是"与对象无关的值"?

C++ 11和C++ 14标准(分别是工作草案)在§3.10.1中说:

prvalue("纯"rvalue)是一个不是xvalue的rvalue.[示例:调用返回类型不是引用的函数的结果是prvalue.诸如12,7.3e5或true之类的文字的值也是prvalue. - 末端的例子]

rvalue(历史上所谓的,因为rvalues可能出现在赋值表达式的右侧)是xvalue,临时对象(12.2)或其子对象,或者是与对象无关的值.

这引出了一个问题:表达式如何成为"与对象无关的值"?

我的印象是,表达式的目的是返回对象或void(我不希望它也是一个值).

这些表达式有一些简单而常见的例子吗?

编辑1

要进一步复杂化,请考虑以下事项:

int const& x = 3;
int&& y = 4;
Run Code Online (Sandbox Code Playgroud)

在§8.3.2.5的上下文中,其中包含最有趣的片段:

[...]引用应初始化以引用有效的对象或功能[...]

§8.5.3.1强化了这一点:

声明为T&或T &&的变量,即"对类型T的引用"(8.3.2),应由类型为T的对象或函数或可转换为T的对象初始化. [...]

c++ language-lawyer c++11 c++14

11
推荐指数
2
解决办法
391
查看次数

确定:: std :: numeric_limits <T>是否可以安全地实例化

类模板::std::numeric_limits<T>只能为类型实例化,类型T可以是函数的返回值,因为它总是定义成员函数,如static constexpr T min() noexcept { return T(); }(更多信息请参见http://www.cplusplus.com/reference/limits/numeric_limits/) c ++ 03或c ++ 11中的特殊版本.

如果T是,即int[2]实例化将立即导致编译时错误,因为int[2]不能是函数的返回值.

::std::numeric_limits使用安全版本进行包装很容易 - 如果确定实例化::std::numeric_limits是否安全的方法是已知的.这是必要的,因为如果可能的话,应该可以访问有问题的功能.

显而易见(显然是错误的)测试方法::std::numeric_limits<T>::is_specialised不起作用,因为它需要实例化有问题的类模板.

有没有办法测试实例化的安全性,最好不要列举所有已知的坏类型?甚至可能是确定任何类模板实例化是否安全的一般技术?

c++ templates c++11 c++03

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

不兼容指针分配的技术合法性

C11标准ISO/IEC 9899:2011(E)规定了§6.5.16.1/ 1中简单指配的以下约束:

以下其中一项应持有:

  • 左操作数具有原子,限定或非限定算术类型,右边有算术类型;
  • 左操作数具有与右侧类型兼容的结构或联合类型的原子,限定或非限定版本;
  • 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,左侧指向的类型具有全部右边指出的那种限定词;
  • 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的指针void,左边指向的类型具有右边指向的所有类型的限定符;
  • 左操作数是一个原子,限定或非限定指针,右边是一个空指针常量; 要么
  • 左操作数的类型为atomic,qualified或nonqualified _Bool,右边是指针.

我感兴趣的是双方都指向不兼容的不同类型的情况void.如果我理解正确,这应该至少调用UB,因为它违反了这个约束.不兼容类型的一个例子应该是(根据§6.2.7和§6.7.2)intdouble.

因此,以下程序应违反:

int main(void) {
  int a = 17;
  double* p;
  p = &a;
  (void)p;
}
Run Code Online (Sandbox Code Playgroud)

gcc和clang都警告"-Wincompatible-pointer-types",但不要中止编译(编译-std=c11 -Wall -Wextra -pedantic).

同样,以下程序只会导致"-Wint-conversion"警告,同时编译就好了.

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

来自C++,我预计这些测试用例中的任何一个都需要使用强制转换来编译.是否有任何理由为什么这两个计划都是标准合法的?或者,是否至少有重要的历史原因支持这种代码风格,即使通过明确使用-std=c11而不是禁用有趣的GNU C扩展-std=gnu11

c gcc clang language-lawyer c11

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

模板参数推导中int a [5]和int(&a)[5]之间的区别

这个问题是关于采用静态已知大小的数组的函数.

以下面的最小程序为例:

#include <iostream>

template<size_t N>
void arrfun_a(int a[N])
{
    for(size_t i = 0; i < N; ++i)
        std::cout << a[i]++ << " ";
}

int main()
{
    int a[] = { 1, 2, 3, 4, 5 };
    arrfun_a<5>(a);
    std::cout << std::endl;
    arrfun_a<5>(a);

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

运行时,打印预期结果:

2 3 4 5 6
3 4 5 6 7
Run Code Online (Sandbox Code Playgroud)

但是,当我试图让我的编译器(VS 2010)推断出5它时could not deduce template argument for 'int [n]' from 'int [5]'.

一些研究导致arrfun_b模板参数推导工作的更新:

template<size_t n>
void arrfun_b(int …
Run Code Online (Sandbox Code Playgroud)

c++ arrays templates template-argument-deduction

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

你可以两次继承同一个班吗?

你可以两次继承同一个班吗?例如:

class Base {

};

class Foo : public Base {

};

class Bar : public Base {

};

class Baz : public Foo, public Bar { 
    //is this legal? 
    // are there restrictions on Base 
    //       (e.g. only virtual methods or a virtual base)?

};
Run Code Online (Sandbox Code Playgroud)

c++

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

动态分配内存

让我们考虑以下两个代码

第一:

for (int i=0;i<10000000;i++)
{
    char* tab = new char[500];
    delete[] tab;
}
Run Code Online (Sandbox Code Playgroud)

第二:

for (int i=0;i<10000000;i++)
{
    char tab[500];
}
Run Code Online (Sandbox Code Playgroud)

峰值内存使用率几乎相同,但第二个代码运行速度比第一个快20倍.

问题
是因为第一个代码数组存储在堆上,而第二个数组存储在堆栈中?

c++ memory-management dynamic

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