auto foo = "You're using g++!";
auto compiler_detector = [foo](auto foo) { std::puts(foo); };
compiler_detector("You're using clang++!");
Run Code Online (Sandbox Code Playgroud)
clang ++ 3.6.0和更新的打印出"你正在使用clang ++!" 并警告捕获 foo未被使用.
g ++ 4.9.0和更新版本打印出"你正在使用g ++!" 并警告该参数 foo未被使用.
什么编译器更准确地遵循C++标准?
这是
struct Example {
int a, b;
Example(int mA, int mB) : a{mA}, b{mB} { }
Example(const Example& mE) : a{mE.a}, b{mE.b} { }
Example(Example&& mE) : a{move(mE.a)}, b{move(mE.b)} { }
Example& operator=(const Example& mE) { a = mE.a; b = mE.b; return *this; }
Example& operator=(Example&& mE) { a = move(mE.a); b = move(mE.b); return *this; }
}
Run Code Online (Sandbox Code Playgroud)
相当于此
struct Example {
int a, b;
Example(int mA, int mB) : a{mA}, b{mB} { }
Example(const Example& mE) = default; …Run Code Online (Sandbox Code Playgroud) 考虑这两种可以代表"可选int"的方法:
using std_optional_int = std::optional<int>;
using my_optional_int = std::pair<int, bool>;
Run Code Online (Sandbox Code Playgroud)
鉴于这两个功能......
auto get_std_optional_int() -> std_optional_int
{
return {42};
}
auto get_my_optional() -> my_optional_int
{
return {42, true};
}
Run Code Online (Sandbox Code Playgroud)
... g ++ trunk和clang ++ trunk (with -std=c++17 -Ofast -fno-exceptions -fno-rtti)产生以下程序集:
get_std_optional_int():
mov rax, rdi
mov DWORD PTR [rdi], 42
mov BYTE PTR [rdi+4], 1
ret
get_my_optional():
movabs rax, 4294967338 // == 0x 0000 0001 0000 002a
ret
Run Code Online (Sandbox Code Playgroud)
为什么get_std_optional_int()需要三个mov指令,而get_my_optional()只需要一个 …
for(auto& entity : memoryManager.getItems()) entity->update(mFrameTime);
Run Code Online (Sandbox Code Playgroud)
如果memoryManager包含1000个项目,那么memoryManager.getItems()在循环开始时会调用1000次还是只调用一次?
编译器是否使用-O2(或-O3)运行任何优化?
(memoryManager.getItems()返回std::vector<Entity*>&)
我创建了一个简单的双向映射类,它通过内部存储两个std::map具有相反键/值类型的实例,并提供用户友好的界面:
template<class T1, class T2> class Bimap
{
std::map<T1, T2> map1;
std::map<T2, T1> map2;
// ...
};
Run Code Online (Sandbox Code Playgroud)
是否有更有效的方法来实现不需要两倍内存的双向映射?
通常如何实施bimap?
编辑:
bimap元素应该是可变的还是不可变的?(更改一个元素map1应该更改键map2,但键是常量,这是不可能的 - 解决方案是什么?)
元素的所有权也是另一个问题:当用户在bimap中插入键值对时,bimap应该复制该键值对并存储它,然后内部第二个映射(具有反转的键/值)应该不复制,但指向原始对.怎么能实现这一目标?
编辑2:
template<typename T> void doSomething(T&& mStuff)
{
auto lambda([&mStuff]{ doStuff(std::forward<T>(mStuff)); });
lambda();
}
Run Code Online (Sandbox Code Playgroud)
mStuff使用&mStuff语法捕获完美转发的变量是否正确?
或者是否有针对完美转发变量的特定捕获语法?
编辑:如果完美转发的变量是参数包怎么办?
在C++ 17中,实现一个overload(fs...)函数是很容易的,在fs...满足任意数量的参数的情况下FunctionObject,它返回一个行为类似于重载的新函数对象fs....例:
template <typename... Ts>
struct overloader : Ts...
{
template <typename... TArgs>
overloader(TArgs&&... xs) : Ts{forward<TArgs>(xs)}...
{
}
using Ts::operator()...;
};
template <typename... Ts>
auto overload(Ts&&... xs)
{
return overloader<decay_t<Ts>...>{forward<Ts>(xs)...};
}
int main()
{
auto o = overload([](char){ cout << "CHAR"; },
[](int) { cout << "INT"; });
o('a'); // prints "CHAR"
o(0); // prints "INT"
}
Run Code Online (Sandbox Code Playgroud)
由于上面的overloader继承Ts...,它需要复制或移动函数对象才能工作.我想要一些提供相同重载行为的东西,但只引用传递的函数对象.
我们称之为假设函数ref_overload(fs...).我的尝试正在使用std::reference_wrapper …
c++ overloading function-object template-meta-programming c++17
问题:传递一个普通的lambda (到一个模板函数),它捕获this并调用一个this没有显式的成员函数,this->不能在gcc上编译.如果lambda不是通用的,或者lambda没有被传递给任何其他函数但是就地调用,那么它将编译为withoit this->.在所有情况下,Clang都很酷.
时间又一轮的铛VS GCC.谁是对的?
template<typename TF>
void call(TF&& f)
{
f(1);
}
struct Example
{
void foo(int){ }
void bar()
{
call([this](auto x){ foo(x); });
}
};
int main()
{
Example{}.bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
bar()=call([this](auto x){ foo(x); });
错误:无法调用成员函数'void Example :: foo(int)'没有对象调用([this](auto x){foo(x);});`
bar()=call([this](auto x){ this->foo(x); });
为什么非放置new表达式和delete表达式实现为内置语言而不是常规函数?
如果我们有...
一种向OS请求/回馈内存的方法
一种显式调用构造函数的方法(放置new)
一种显式调用析构函数的方法(~T())
...为什么不能放置new,delete只是标准库中的常规功能?例:
template <typename T, typename... Ts>
T* library_new(Ts&&... xs)
{
auto* ptr = /* request enough memory for `T` from OS */;
new (ptr) T(std::forward<Ts>(xs)...);
return ptr;
}
template <typename T>
void library_delete(T* ptr)
{
ptr->~T();
/* reclaim memory for `T` from OS */
}
Run Code Online (Sandbox Code Playgroud) 让我说我有
std::tuple<T0, T1, T2> my_tuple{x0, x1, x2};
Run Code Online (Sandbox Code Playgroud)
其中T0,T1和T2是值类型(即没有混叠是可能的).
只要每个线程访问不同的元素,访问my_tuple元素并从多个线程同时改变它们是否安全std::get?
例:
template <typename T>
void process(T& x) { /* mutate `x` */ }
// ...
std::thread{[&]{ process(std::get<0>(my_tuple)); }}.detach();
std::thread{[&]{ process(std::get<1>(my_tuple)); }}.detach();
std::thread{[&]{ process(std::get<2>(my_tuple)); }}.detach();
Run Code Online (Sandbox Code Playgroud)
本能地,我会说它是安全的,my_tuple可以被认为是struct { T0 x0; T1 x1; T2 x2; };......但它是否由标准保证?
c++ ×10
c++11 ×6
lambda ×3
c++14 ×2
c++17 ×2
performance ×2
assembly ×1
bimap ×1
constructor ×1
default ×1
for-loop ×1
foreach ×1
map ×1
new-operator ×1
overloading ×1
shadowing ×1
stdtuple ×1
this ×1
x86-64 ×1