小编Red*_*III的帖子

std :: function vs template

感谢C++ 11,我们收到了std::functionfunctor包装器系列.不幸的是,我一直只听到关于这些新增内容的不好的事情.最受欢迎的是它们非常慢.我对它进行了测试,与模板相比,它们真的很糟糕.

#include <iostream>
#include <functional>
#include <string>
#include <chrono>

template <typename F>
float calc1(F f) { return -1.0f * f(3.3f) + 666.0f; }

float calc2(std::function<float(float)> f) { return -1.0f * f(3.3f) + 666.0f; }

int main() {
    using namespace std::chrono;

    const auto tp1 = system_clock::now();
    for (int i = 0; i < 1e8; ++i) {
        calc1([](float arg){ return arg * 0.5f; });
    }
    const auto tp2 = high_resolution_clock::now();

    const auto d = duration_cast<milliseconds>(tp2 - tp1);  
    std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 std-function

156
推荐指数
7
解决办法
6万
查看次数

保证静态对象的静态(常量)初始化

首要问题是:程序员如何确保通过静态初始化而不是通过动态初始化来初始化他的非本地静态变量?

由于始终进行零初始化,因此应该查看常量初始化.

3.6.2.2对象的常量初始化器o是一个表达式,它是一个常量表达式,除了它也可以为o及其子对象调用constexpr构造函数,即使这些对象是非文字类类型[注意:这样的类可能有一个非平凡的析构函数 - 注意事项].执行常量初始化:

- 如果在具有静态或线程存储持续时间的引用的初始值设定项中出现的每个完整表达式(包括隐式转换)是常量表达式(5.19)并且引用绑定到指定具有静态存储持续时间的对象的左值或者临时的(见12.2);

- 如果具有静态或线程存储持续时间的对象由构造函数调用初始化,并且初始化full-expression是对象的常量初始化器 ;

- 如果具有静态或线程存储持续时间的对象未通过构造函数调用初始化,并且该对象是值初始化的,或者其初始化程序中出现的每个完整表达式都是常量表达式.

我省略了引用,因为它在我的情况下并不重要.如何理解标准是有3种情况:

  1. 构造函数
  2. no-ctor和值初始化
  3. 没有和不断表达

假设我有以下课程:

struct X {
  bool flag = false;
  // = {} will break VS2013 CTP so in that case use the
  // regular ctor, which sadly still can't be declared constexpr
  std::aligned_storage<sizeof(int), alignof(int)>::type storage = {};
};
Run Code Online (Sandbox Code Playgroud)

据我所知,这个类对于常量初始化是完全有效的(每个元素都可以不断初始化).这是真的?

这个类需要constexpr构造函数吗?

C++ 11和C++ 98是否保证了常量初始化?

附带问题:如果是/ dll,静态初始化什么时候完成?在加载时间内,还是可能会进一步延迟?

c++ c++11

24
推荐指数
1
解决办法
1000
查看次数

EntityFramework代码优先自定义连接字符串和迁移

当我使用默认连接字符串(从中读取app.config)创建上下文时,将创建数据库并且迁移工作 - 基本上所有内容都是有序的.而以编程方式(使用SqlConnectionStringBuilder)创建连接字符串时:

  • 数据库不存在时不创建数据库(场景A);
  • CreateDbIfNotExists()创建最新版本的数据库模型,但调用迁移机制(方案B).

A我希望访问数据库时抛出异常,因为 - 显然 - 它不在那里.在B数据库中创建正确的迁移机制不会被调用,就像标准连接字符串中的情况一样.

app.config:" Data Source=localhost\\SQLEXPRESS;Initial Catalog=Db13;User ID=xxx;Password=xxx"

建设者:

sqlBuilder.DataSource = x.DbHost;
sqlBuilder.InitialCatalog = x.DbName;
sqlBuilder.UserID = x.DbUser;
sqlBuilder.Password = x.DbPassword;
Run Code Online (Sandbox Code Playgroud)

初始化程序:

Database.SetInitializer(
    new MigrateDatabaseToLatestVersion<
        MyContext,
        Migrations.Configuration
    >()
);
Run Code Online (Sandbox Code Playgroud)

规范:实体框架:5.0,DB:SQL Server Express 2008

entity-framework connection-string ef-code-first ef-migrations

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

使用std :: initializer_list时防止缩小转换

#include <iostream>

struct X {
    X(std::initializer_list<int> list) { std::cout << "list" << std::endl; }
    X(float f) { std::cout << "float" << std::endl; }
};

int main() {
    int x { 1.0f };
    X a(1);     // float (implicit conversion)
    X b{1};     // list
    X c(1.0f);  // float
    X d{1.0f};  // list (narrowing conversion) ARG!!!

    // warning: narrowing conversion of '1.0e+0f' from 'float' to 'int'
    // inside { } [-Wnarrowing]
}
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以std::initializer_list从过载列表中删除(即,使非列表ctors更有利),而不是使用()初始化,或者至少禁止缩小转换(除了将警告变为错误)?

我使用的是使用GCC 4.8的http://coliru.stacked-crooked.com/编译器.

c++ initializer-list c++11

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

C++中的临时,引用和三元运算符

我有以下基本代码:

struct X {
  X(const char* descr) {...}
  ~X() {...} // Not virtual
  virtual void foo() const {...}
};

struct Y : public X {
  Y(const char* descr) {...}
  ~Y() {...} // Not virtual
  virtual void foo() const {...}
};


const X& factory() {
    static X sampleX{"staticX"};
    static Y sampleY{"staticY"};
    return X or Y depending of the test case;
};
Run Code Online (Sandbox Code Playgroud)

4个测试用例:

只是Y =好的

const X& var = Y{"temporaryY"};
var.foo();
Run Code Online (Sandbox Code Playgroud)

结果:

X::X() // base temporaryY
Y::Y() // temporaryY
Y::foo()
Y::~Y() …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

7
推荐指数
2
解决办法
939
查看次数

缓存对齐的堆栈变量

使用新的C++ 11对齐工具,我想确保一组临时(堆栈)变量位于一个缓存行中.我的第一次天真尝试如下:

int main() {
    alignas(64) int a; // 0x7fffc58aac80, properly aligned at 64
    int b; // 0x7fffc58aac7c
    int c; // 0x7fffc58aac78
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

愚蠢的我!堆栈不分配变量这种方式,从而a将在不同的缓存行比bc.

这是否意味着正确对齐多个变量唯一方法是通过聚合

struct alignas(64) Abc {
   int x;
   int y;
   int z;
};

int main() {
   Abc foo;
   // x 0x7fff40c2d3c0 (aligned at 64)
   // y 0x7fff40c2d3c4
   // z 0x7fff40c2d3c8   
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器:Clang 3.2

c++ memory-alignment c++11

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

复制elision和临时绑定的ref对象

C++草案规定:

12.8p31在下列情况下允许复制/移动操作的省略,称为复制省略(可以合并以消除多份复制):

(......)

  • 当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动

换一种说法:

X MakeX() {
   return X(); // Copy elided
}

X MakeX() {
   const X& x = X(); // Copy not elided
   return x;
}
Run Code Online (Sandbox Code Playgroud)

引用受限制的原因是什么

请不要集中在下面的例子中的有效性,因为它们只是为了举例说明,我看不到临时和基准之间的差异(恕我直言).

一方面通过引用引用,我们允许其他对等体为同一个对象设置别名,而调用者则MakeX()希望它是安全和干净的.

class Y {
public:
    Y(const X& x) : _xRef(x) {}
private:
    const X& _xRef;
};

X MakeX() {
    const X& x = X();
    Y y{x};
    StaticStuff::send(y);
    return x; // Oops, I promised to return a clean,
              // new object, but in fact …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

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

C++原子和跨线程可见性

AFAIK C++ atomics(<atomic>)系列提供3个好处:

  • 原始指令不可分割(没有脏读),
  • 内存排序(包括CPU和编译器)和
  • 跨线程可见性/变化传播.

我不确定第三个子弹,因此请看下面的例子.

#include <atomic>

std::atomic_bool a_flag = ATOMIC_VAR_INIT(false);
struct Data {
    int x;
    long long y;
    char const* z;
} data;

void thread0()
{
    // due to "release" the data will be written to memory
    // exactly in the following order: x -> y -> z
    data.x = 1;
    data.y = 100;
    data.z = "foo";
    // there can be an arbitrary delay between the write 
    // to any of the members and it's …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading atomicity c++11

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

clang 格式控制具有多行成员字段/函数访问的缩进

考虑以下代码段(使用类似构建器的模式来构造对象):

auto const ci = ::vk::InstanceCreateInfo{}.setPApplicationInfo(&ai).setEnabledExtensionCount(count).setPpEnabledExtensionNames(extensionsArray).setEnabledLayerCount(requiredLayers.size()).setPpEnabledLayerNames(requiredLayers.data());
Run Code Online (Sandbox Code Playgroud)

我希望它可以被格式化为:

auto const ci = ::vk::InstanceCreateInfo{}
    .setPApplicationInfo(&ai)
    .setEnabledExtensionCount(count)
    .setPpEnabledExtensionNames(extensionsArray)
    .setEnabledLayerCount(requiredLayers.size())
    .setPpEnabledLayerNames(requiredLayers.data());
Run Code Online (Sandbox Code Playgroud)

但 clang 坚持认为:

auto const ci = ::vk::InstanceCreateInfo{}
                  .setPApplicationInfo(&ai)
                  .setEnabledExtensionCount(count)
                  .setPpEnabledExtensionNames(extensionsArray)
                  .setEnabledLayerCount(requiredLayers.size())
                  .setPpEnabledLayerNames(requiredLayers.data());
Run Code Online (Sandbox Code Playgroud)

我怎样才能控制它?似乎没有选择(比如AlignMemberAccess)。

c++ clang-format

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

C++ 11如何在编译时识别原子类型(通过mtl或者定义)?

我想知道是否有可能确定给定的类型是否是原子的(这意味着你可以在没有互斥的情况下对其执行操作,而不是让自己处于危险之中).

我想知道是否有一些atomic(type)定义可以确定类型是否是原子的.为了创建类似的东西DEFINE( (int)(do) );会创建伪代码,如:

   int _do;

#if !atomic(int)
    mutex do_mutex;
#endif   

   void set_do(int do)
   {
#if atomic(int)
       _do = do;
#else
       lock(do_mutex);
       _do = do;
#endif
   }
Run Code Online (Sandbox Code Playgroud)

如果type是atomic(如果需要,使用boost),那么有没有办法检查define/mtl级别.

c++ boost atomic c++11

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

C++ 模板的实例化惰性规则

AFAIK 模板实例化只有两个“阶段”:

  • 默认(立即),
  • 延迟(懒惰)。

默认用于以下成员:

  • typedef
  • 成员字段。

延期:

  • 功能(静态或非静态),
  • 嵌套类型。

这是正确的,或者还有其他一些关于编译器渴望实例化模板的问题/规则?

c++ templates

0
推荐指数
1
解决办法
142
查看次数