小编Mar*_*ark的帖子

通过价值传递与通过右值参考传递

我什么时候应该声明我的功能:

void foo(Widget w);

而不是

void foo(Widget&& w);

假设这是唯一的重载(例如,我选择一个或另一个,不是两个,也没有其他重载).没有涉及模板.假设该函数foo需要所有权Widget(例如const Widget&,不是本讨论的一部分).我对这些情况范围之外的任何答案都不感兴趣.请参阅帖子末尾的附录,了解为什么这些约束是问题的一部分.

我和我的同事可以提出的主要区别是rvalue参考参数强制您明确复制副本.调用者负责制作一个显式副本,然后在std::move需要副本时将其传入.在按值传递的情况下,隐藏了副本的成本:

    //If foo is a pass by value function, calling + making a copy:
    Widget x{};
    foo(x); //Implicit copy
    //Not shown: continues to use x locally

    //If foo is a pass by rvalue reference function, calling + making a copy:
    Widget x{};
    //foo(x); //This would be a compiler error
    auto copy = x; //Explicit copy
    foo(std::move(copy));
    //Not shown: continues …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++14

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

在C++ 11中同时使用virtual和override关键字有什么微妙之处吗?

在C++中同时使用virtualoverride使用函数是危险的吗?那是否会让你因重载而产生歧义?

显然,virtual必须在基类中使用,这将是愚蠢的,不使用override派生类,但它实际上是有问题的使用virtual override在派生类?

试图确定这是一个风格或正确的问题.

例:

class Widget {
  virtual void transmogrify() = 0;
}

class Gadget : public Widget {
  virtual void transmogrify() override {}
}
Run Code Online (Sandbox Code Playgroud)

c++ c++11

21
推荐指数
2
解决办法
1293
查看次数

在int和double之间转换有多贵?

我经常看到代码将int转换为双精度转换为双精度并再次转换(有时候出于好的理由,有时候没有),而且我刚刚想到这似乎是我程序中的"隐藏"成本.我们假设转换方法是截断.

那么,它有多贵?我确定它会因硬件而异,所以让我们假设一个新的英特尔处理器(Haswell,如果你愿意,虽然我会采取任何措施).我会感兴趣的一些指标(虽然一个好的答案不需要全部):

  1. 生成的指令数
  2. 使用的周期数
  3. 与基本算术运算相比的相对成本

我还假设我们最敏锐地体验慢转换的影响的方式是关于功率使用而不是执行速度,因为我们每秒可以执行多少次计算相对于实际到达的数据量的差异在每秒CPU.

c++ x86 c++-cli x86-64 micro-optimization

20
推荐指数
2
解决办法
6558
查看次数

可以在C++ 14 constexpr函数中使用for循环实例化模板吗?

我一直在乱搞SVN构建的clang来试验放松的规则constexpr.我之前无法确定的一件事是,是否可以在constexpr函数中在编译时循环遍历元组内的元素.

因为我没有要测试的符合C++ 14的标准库,所以我准备了以下等效测试:

template<int N>
constexpr int foo() {
  return N;
}

constexpr int getSum() {
  auto sum = 0;
  for (auto i = 0; i < 10; ++i) {
    sum += foo<i>();
  }
  return sum;
}

constexpr auto sum = getSum();
Run Code Online (Sandbox Code Playgroud)

这里有趣的部分是foo<i>().在非constexpr函数中,我希望它无法编译,因为您根本无法使用运行时int来生成模板的编译时实例化.constexpr但是,因为这是一个功能,我怀疑这是否可行.特别是,该值在编译时是已知的,即使它允许变异.

我知道以下代码编译:

constexpr auto nValue = 2;
foo<nValue>();
Run Code Online (Sandbox Code Playgroud)

在SVN clang中,我的第一个例子没有:

test2.cpp:19:12: error: no matching function for call to 'foo'
    sum += foo();
           ^~~~~~
test2.cpp:11:15: note: candidate template ignored: invalid explicitly-specified …

c++ constexpr c++14

16
推荐指数
1
解决办法
3231
查看次数

在C++ 11中使用:: new的线程安全性

我确信,在实践中,使用::new是线程安全的.我的问题是标准的哪一部分提供了保证,如果有的话?这是一个惯例吗?这是标准为实现提供了很多自由度(比如关于每种数据类型的相对宽松的约束)以支持各种硬件的东西吗?

我希望C++ 11标准中只有一行明确指定" ::new必须是线程安全的实现".

我也很想看到一些关于操作员新过载的线程安全性的标准.我想,他们也需要被需要是线程安全的,但这些功能还没有下全面担保属于这一常量=>线程安全(在C++ 11).

谢谢!

c++ concurrency multithreading c++11

12
推荐指数
1
解决办法
917
查看次数

为成员函数自动生成const重载

我试图inout在C++中实现D语言关键字的语义(只是为了它的乐趣).

根据具体情况,它基本上表示两件事之一:

  1. "这个函数的结果将与它的一个参数具有相同的常量."
  2. "这个成员函数的结果与你调用它的实例具有相同的常量."

在编写像beginend等的成员函数时很有用.

我能够相对轻松地创建第一个案例的有效实现(尽管界面肯定不是很漂亮):http://ideone.com/wgaDJJ

然而,第二个似乎是我最好的猜测所不可能的.当你使用模板时,你只能得到这种"自动const过载生成",但据我所知,你不能模仿"this"这个论点.特别是,您会注意到此代码无法正常工作/编译:http://ideone.com/W4fTa4

想知道:

  1. 我错过了什么吗?是否可以在不诉诸宏或代码重复的情况下实现第二种情况?
  2. 有人知道是否有关于这个问题的WG21标准提案?(不一定inout,只是关于主题的任何事情)
  3. 处理这个问题的行业标准是什么?(这是我玩弄的一个可能不太可怕的选项:http://ideone.com/PW0vK4)

c++ c++11

10
推荐指数
1
解决办法
327
查看次数

container.clear()是否可以释放/重新分配内部缓冲区?

如果我有一个容器,并调用clear()就可以了,这是否只是破坏里面的所有元素,或者它实际上免费/内部也分配新的内存?这种行为是否超出了C++标准的范围?

这归结为:

unordered_set<int> mySet { 1, 2, 3, 4, 5 };
mySet.reserve(1000);
mySet.clear();

//Is this pointless/redundant
//or should I treat my container like it was just constructed?
mySet.reserve(1000);
Run Code Online (Sandbox Code Playgroud)

对ideone的快速测试(http://ideone.com/XQi8IT)显示在调用clear之后内部缓冲区被保留.所以,至少对于新版本的g ++ unordered_set来说就是这样.我的问题是1)标准说什么,如果有的话2)这种行为是否在所有容器中是一致的.

c++ c++11

10
推荐指数
1
解决办法
454
查看次数

为什么std :: priority_queue没有clear()成员函数

我今天做了一些黑客攻击,发现std :: priority_queue没有clear()成员函数.是否有任何技术原因可以解释为什么标准委员会可能会将其排除在外?

为了清楚起见,我知道通过赋值可以很容易地解决这个问题:

oldPQ = std::priority_queue<int>{};
Run Code Online (Sandbox Code Playgroud)

这个解决方案不太理想,因为:

  1. 它要求您重复该类型 - 这不会继续在维护下工作.正如@chris在下面指出的那样,如果您使用的是默认构造函数,则可以简化此操作,但如果您有自定义比较器,则可能无法实现.
  2. std::priority_queue不能在需要clear()成员函数的模板化函数中使用.
  3. 通常不希望它不满足其他容器提供的公共接口.特别是,一切从std::forward_liststd::unordered_mapstd::stringclear().我注意到的唯一其他异常是std :: array,对于这些异常,语义没有意义,std::stack而且std::queue,在std::deque没有任何额外工作的情况下,语义更有问题.

一个看似问题的项目,但实际上不一定是:因为用于的内部容器std::priority_queue是模板化的,并且可能没有自己的clear()成员函数,这会产生一个有趣的问题,特别是它提出了向后兼容性的问题.这不是问题,因为:

  1. 对于不提供的内部容器,clear()只要没有人试图调用std::priority_queue::clear(),代码将继续编译.
  2. SFINAE可能仍然可以通过clear()在内部容器可用时调用它来提供新接口(清除成员),如果不可用则反复弹出.

我认为这是C++标准中的一个缺陷.假设技术讨论没有为省略此方法的原因提供强有力的理由,我打算继续创建标准提案.

编辑:

似乎这是在委员会内处理的(请注意上一篇文章):https://groups.google.com/a/isocpp.org/forum/? fromgroups#!searchin/std-discussion/clear/std-discussion/_mYobAFBOrM/TY-2347w1T4J

http://wg21.cmeerw.net/lwg/issue2194

c++ stl c++11

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

减去两个nullptr值保证为零?

是否由C++标准保证,如果我有两个相同类型的指针,其值等于nullptr,那些指针之间的差异等于0?

在伪数学符号中,以下谓词是否成立?

ForAll x ForAll y(x == nullptr)^(y == nullptr) - >(x - y == 0)

我能想到的最简单的代码示例:

int* x = nullptr;
int* y = nullptr;
assert(x - y == 0);
Run Code Online (Sandbox Code Playgroud)

我想这可以归结为:是否有可能有一个有效的C++标准实现,其中有多个位表示nullptr只能比较为相等,因为相等运算符做了一些魔术?

c++ c++11

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

如何替换目标文件中的符号

我想重写目标文件,以便将大多数函数的地址更改为无操作函数。我怎样才能做到这一点?

更多上下文:在 C++ 中,我想默认自动模拟所有函数。从打电话a()a() {}打电话b()b() {}真正a()打电话replacement() {}b()也打电话(相同)replacement() {}

到目前为止我考虑过的事情:

  • objcopy --redefine-syms=filename- 这改变了符号的名称,而不是它的地址。
  • 使用链接器的--wrap参数 - 这需要__wrap_NameOfWrappedThing为我想要包装的每个东西编译一个不同的符号,并且通常看起来它不能很好地缩放。

c++ linux linker ld object-files

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

is_const <const int&> :: value是false - 为什么?

为什么这个静态断言会引发火灾?

static_assert(std::is_const<const int&>::value, "Pain");
Run Code Online (Sandbox Code Playgroud)

获得一个语法(为什么实现会这样做)和一个语义推理(为什么他们会设计这种类型特征的接口来做到这一点)真是太棒了.

我知道可以通过std::remove_reference电话来获得预期的结果,但我不确定为什么这是必要的.

c++ c++11

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

使用静态成员函数的别名?

有没有办法在C++中为静态成员函数设置别名?我希望能够将其纳入范围,以便我不需要完全限定名称.

基本上是这样的:

struct Foo {
  static void bar() {}
};

using baz = Foo::bar; //Does not compile

void test() { baz(); } //Goal is that this should compile
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是使用std::bind(如在auto baz = std::bind(Foo::bar);)或函数指针(如在auto baz = Foo::bar;),但这是不能令人满意的,因为对于我希望能够使用别名的每个函数,我需要为该函数创建一个单独的变量,或者而是在全局/静态范围内使别名变量可用.

c++ c++11 c++14

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

用C++拦截睡眠调用

有没有办法在C++中拦截对睡眠和类似睡眠的函数的调用?我希望能够用无操作或替代方案替换实现,从而增加睡眠时间.我想这将有助于确定并发程序的正确性以及确定测试中的片状来源.

我在一个巨大的代码库上运行,所以使用包装函数会不太令人满意.也许有一种方法可以使用ptrace或valgrind等程序用来拦截malloc的相同技术?

c++ c++11

2
推荐指数
1
解决办法
255
查看次数