小编Lar*_*ars的帖子

D与C++相比有多快?

我喜欢D的一些功能,但如果它们带来运行时惩罚会有兴趣吗?

为了比较,我实现了一个简单的程序,用C++和D计算许多短向量的标量积.结果令人惊讶:

  • D:18.9秒[最终运行时见下文]
  • C++:3.8秒

C++真的几乎快了五倍,还是我在D程序中犯了错误?

我在一个温和的最近的Linux桌面上用g ++ -O3(gcc-snapshot 2011-02-19)和D和dmd -O(dmd 2.052)编译了C++.结果可在多次运行中重现,标准偏差可忽略不计.

这里的C++程序:

#include <iostream>
#include <random>
#include <chrono>
#include <string>

#include <vector>
#include <array>

typedef std::chrono::duration<long, std::ratio<1, 1000>> millisecs;
template <typename _T>
long time_since(std::chrono::time_point<_T>& time) {
      long tm = std::chrono::duration_cast<millisecs>( std::chrono::system_clock::now() - time).count();
  time = std::chrono::system_clock::now();
  return tm;
}

const long N = 20000;
const int size = 10;

typedef int value_type;
typedef long long result_type;
typedef std::vector<value_type> vector_t;
typedef typename vector_t::size_type size_type;

inline value_type scalar_product(const vector_t& x, const vector_t& …
Run Code Online (Sandbox Code Playgroud)

c++ performance d runtime

130
推荐指数
7
解决办法
3万
查看次数

为什么**不**声明一个函数是`constexpr`?

任何只包含return语句的函数都可以声明 constexpr,因此如果所有参数都是,constexpr并且只constexpr在其体内调用函数,则允许在编译时进行计算.有没有理由不宣布任何此类功能constexpr

例:

  constexpr int sum(int x, int y) { return x + y; }
  constexpr i = 10;
  static_assert(sum(i, 13) == 23, "sum correct");
Run Code Online (Sandbox Code Playgroud)

任何人都可以提供一个例子来声明一个函数constexpr 会造成什么伤害吗?


一些初步想法:

即使没有充分的理由宣布一个函数,constexpr我也无法想象该constexpr关键字具有过渡角色:它在代码中的缺失不需要编译时评估将允许那些不实现编译时评估的编译器仍然编译该代码(但是在使用需要它们的代码上可靠地失败constexpr).

但是我不明白:如果没有充分的理由不宣布函数constexpr,为什么标准库中的每个函数都没有被声明constexpr?(你不能说它还没有完成,因为还没有足够的时间去做,因为为所有人做这件事是明智的 - 与决定每一个功能是否成功相反constexpr.) - - 我知道N2976 故意不要求cstrs用于许多标准库类型,例如容器,因为这对于可能的实现来说太有限了.让我们从参数中排除它们并且只是想知道:一旦标准库中的一个constexpr类型实际上有一个cstr,为什么不是每个函数都在它上面声明constexpr

在大多数情况下,你也不能说你可能不想constexpr仅仅因为你没有设想任何编译时使用而声明一个函数 :因为如果其他人退出.将使用您的代码,他们可能会看到您没有这样的用途.(当然,也可以用于类型特征类型和类似的东西.)

所以我想有一个很好的理由和一个故意不宣布功能的好例子constexpr

("每个函数"我总是指:满足存在要求的每个函数constexpr,即被定义为单个return语句,只接受带有constexpr cstrs的类型的参数,并且只调用constexpr …

c++ const function-declaration constexpr c++11

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

如何在编译时查询constexpr std :: tuple?

在C++ 0x中,可以创建一个constexpr std :: tuple,例如

#include <tuple>
constexpr int i = 10;
constexpr float f = 2.4f;
constexpr double d = -10.4;
constexpr std::tuple<int, float, double> tup(i, f, d);
Run Code Online (Sandbox Code Playgroud)

还可以在运行时查询std :: tuple,例如通过

int i2 = std::get<0>(tup);
Run Code Online (Sandbox Code Playgroud)

但是在编译时无法查询它,例如,

constexpr int i2 = std::get<0>(tup);
Run Code Online (Sandbox Code Playgroud)

将抛出编译错误(至少使用最新的g ++快照2011-02-19).

有没有其他方法在编译时查询constexpr std :: tuple?

如果没有,是否有一个概念上的原因,为什么不应该查询它?

(我知道避免使用std :: tuple,例如,通过使用boost :: mpl或boost :: fusion,但不知何故,如果不在新标准中使用元组类,这听起来是错误的......).

顺便问一下,有人知道为什么

  constexpr std::tuple<int, float, double> tup(i, f, d);
Run Code Online (Sandbox Code Playgroud)

编译好,但是

  constexpr std::tuple<int, float, double> tup(10, 2.4f, -10.4);
Run Code Online (Sandbox Code Playgroud)

不?

非常感谢提前! - 啦

c++ tuples const c++11

20
推荐指数
1
解决办法
3041
查看次数

为什么std :: forward丢弃constexpr-ness?

如果没有声明constexpr,std::forward将丢弃constexpr-ness以用于转发参数的任何函数.为什么std::forward不宣布constexpr自己这样可以保留constexpr-ness?

示例:(使用g ++ snapshot-2011-02-19测试)

#include <utility>

template <typename T> constexpr int f(T x) { return -13;}
template <typename T> constexpr int g(T&& x) { return f(std::forward<T>(x));}

int main() {
  constexpr int j = f(3.5f);
  // next line does not compile: 
  // error: ‘constexpr int g(T&&) [with T = float]’ is not a constexpr function
  constexpr int j2 = g(3.5f);
}
Run Code Online (Sandbox Code Playgroud)

注意:从技术上讲,很容易制作std::forwardconstexpr,例如,如此(请注意,g std::forward已被替换为fix::forward):

#include <utility>

namespace fix …
Run Code Online (Sandbox Code Playgroud)

c++ const move-semantics perfect-forwarding c++11

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

如何在boost :: mpl算法中使用std :: tuple类型?

boost::mpl算法似乎不能够在工作std::tuple类型的开箱即用的例如,下列不编译(升压1.46.0,G ++快照2011-02-19):

#include <tuple>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>

namespace mpl=boost::mpl;

typedef mpl::vector<int,float,bool> types;
static_assert(mpl::contains<types, float>::value, "vector contains bool");

typedef std::tuple<int,float,bool> types2;
// the following does not compile:
// error: no class template named ‘apply’ in ‘struct boost::mpl::contains_impl<boost::mpl::non_sequence_tag>’
static_assert(mpl::contains<types2, float>::value, "tuple contains bool");
Run Code Online (Sandbox Code Playgroud)

使boost::mpl算法工作的最简单方法是什么std::tuple

  • 是evtl. boost::fusion提供此功能(因为它这样做boost::tuple)?
  • 如果不是,它有可能结转的融合实现boost::tuplestd::tuple容易吗?
  • 如果不是,我是否真的必须实现MPL文档中列出的所有内部元函数或哪些足够?(该文档只是说" 许多固有元函数提供了一个默认的实现,将在大多数情况下工作 ",但目前尚不清楚哪些准确.还有一些测试只提供开始和结束并没有导致我到任何地方).

c++ tuples boost-mpl c++11

6
推荐指数
2
解决办法
3858
查看次数

如何在模板基类中调用模板成员函数?

在基类中调用非模板化成员函数时,可以将其名称导入using到派生类中,然后使用它.这也适用于基类中的模板成员函数吗?

只是using它不起作用(使用g ++ - snapshot-20110219 -std = c ++ 0x):

template <typename T>
struct A {
  template <typename T2> void f() {  }
};

template <typename T>
struct B : A<T> {
  using A<T>::f;

  template <typename T2> void g() {
    // g++ throws an error for the following line: expected primary expression before `>`
    f<T2>();
  }
};

int main() {
  B<float> b;
  b.g<int>();
}
Run Code Online (Sandbox Code Playgroud)

我知道明确地为基类添加前缀

    A<T>::template f<T2>();
Run Code Online (Sandbox Code Playgroud)

工作正常,但问题是:是否有可能没有和使用简单的使用声明(就像它f不是模板函数的情况一样)?

万一这是不可能的,有谁知道为什么?

c++ templates using member-functions c++11

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