感谢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) 首要问题是:程序员如何确保通过静态初始化而不是通过动态初始化来初始化他的非本地静态变量?
由于始终进行零初始化,因此应该查看常量初始化.
3.6.2.2对象的常量初始化器o是一个表达式,它是一个常量表达式,除了它也可以为o及其子对象调用constexpr构造函数,即使这些对象是非文字类类型[注意:这样的类可能有一个非平凡的析构函数 - 注意事项].执行常量初始化:
- 如果在具有静态或线程存储持续时间的引用的初始值设定项中出现的每个完整表达式(包括隐式转换)是常量表达式(5.19)并且引用绑定到指定具有静态存储持续时间的对象的左值或者临时的(见12.2);
- 如果具有静态或线程存储持续时间的对象由构造函数调用初始化,并且初始化full-expression是对象的常量初始化器 ;
- 如果具有静态或线程存储持续时间的对象未通过构造函数调用初始化,并且该对象是值初始化的,或者其初始化程序中出现的每个完整表达式都是常量表达式.
我省略了引用,因为它在我的情况下并不重要.我如何理解标准是有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,静态初始化什么时候完成?在加载时间内,还是可能会进一步延迟?
当我使用默认连接字符串(从中读取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
#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/编译器.
我有以下基本代码:
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++ 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将在不同的缓存行比b和c.
这是否意味着正确对齐多个变量的唯一方法是通过聚合?
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++草案规定:
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) AFAIK C++ atomics(<atomic>)系列提供3个好处:
我不确定第三个子弹,因此请看下面的例子.
#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) 考虑以下代码段(使用类似构建器的模式来构造对象):
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)。
我想知道是否有可能确定给定的类型是否是原子的(这意味着你可以在没有互斥的情况下对其执行操作,而不是让自己处于危险之中).
我想知道是否有一些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级别.
AFAIK 模板实例化只有两个“阶段”:
默认用于以下成员:
typedef,延期:
这是正确的,或者还有其他一些关于编译器渴望实例化模板的问题/规则?