我有以下代码:
// Case #1
float f = 1.0f;
float f2 = sqrt(f * pi);
// Case #2
double d = 1.0;
double d2 = sqrt(d * pi);
Run Code Online (Sandbox Code Playgroud)
有什么办法来定义变量pi,以便operator*与sqrt将在操作floatS IN案例#1,但在操作double中的情况#2秒?
也许C++ 14变量模板可能有用吗?
在特殊情况下,我希望我的程序停止处理,输出错误std::cerr,清理和退出.
但是,调用exit()不会调用已构造的任何对象的所有析构函数.我想要很好地调用析构函数,所以我将所有代码包装在一个try-catch块中,如下所示:
int main(int argc, char** argv){
try {
bool something_is_not_right = false;
/* lots of variables declared here */
/* some code that might set something_is_not_right to true goes here */
if(something_is_not_right){
std::cerr << "something is not right!!!" << std::endl;
throw '\0'; // dummy unused variable for throwing.
}
}
catch (...) {}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我可以保证破坏所有变量.但我似乎无法找到让C++ throw无所作为的方法. throw;在C++中有特殊意义; 它什么都不扔.
有什么方法可以throw吗?
我想编写一个foo应该调用operator()其参数的函数,如下面(破碎)代码所示:
template <typename T> void foo(const T& x){
x();
}
struct MyFunctor{
int data;
void operator()(){
/* stuff that might modify the data */
}
};
int main()
{
foo(MyFunctor{});
}
Run Code Online (Sandbox Code Playgroud)
显然代码不起作用,因为operator()它是非的const,但foo()需要它的参数const.
作为模板函数,foo()应该使用两个const和非const函子,并且不要挑剔const它的参数的性质.
如果我foo()通过删除const以下内容进行更改:
template <typename T> void foo(T& x) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
...它也不起作用,因为你无法将右值引用转换为非const左值引用,因此foo(MyFunctor{})无法调用.
更改foo()为转发引用可解决所有问题:
template <typename T> …Run Code Online (Sandbox Code Playgroud) C++11 引入了引用限定成员函数以及完美转发的功能。但我们可以将它们混合在一起吗?
考虑这个(工作)示例:
struct bar{
std::string str;
void do_stuff() & {
/* version 1 */
}
void do_stuff() && {
/* version 2 */
}
};
struct foo{
bar data;
void do_stuff() & {
data.do_stuff();
}
void do_stuff() && {
std::move(data).do_stuff();
}
};
int main(){
foo f;
f.do_stuff() // calls version 1 of bar::do_stuff()
std::move(f).do_stuff() // calls version 2 of bar::do_stuff()
}
Run Code Online (Sandbox Code Playgroud)
在内部main(),第一个调用调用版本 1 或bar::do_stuff(),第二个调用调用版本 2 或bar::do_stuff()。中存在一些重复的代码foo::do_stuff()。如果 ref-qualifiers 用于除隐含的参数之外的参数*this,我们可以轻松地进行完美转发:
template …Run Code Online (Sandbox Code Playgroud) C++ 17为标准库添加了并行扩展(例如std::sort(std::execution::par_unseq, arr, arr + 1000),允许使用多个线程和向量指令进行排序).
我注意到微软的实验性实现提到VC++编译器缺乏对这里做矢量化的支持,这让我感到惊讶 - 我认为现代C++编译器能够推断出循环的可矢量化,但显然VC++编译器/优化器无法生成SIMD代码即使明确告知这样做.看似缺乏自动矢量化支持与2011年关于Quora的问题的答案相矛盾,这表明编译器将在可能的情况下进行矢量化.
也许,编译器只会对非常明显的情况进行矢量化,例如a std::array<int, 4>,而且只不过是这样,因此C++ 17的显式并行化会很有用.
因此我的问题是:当没有明确告知这样做时,当前的编译器会自动向量化我的代码吗?(为了使这个问题更具体,让我们将其缩小到支持SIMD的Intel x86 CPU,以及最新版本的GCC,Clang,MSVC和ICC.)
作为扩展:其他语言的编译器是否可以做更好的自动矢量化(可能是由于语言设计)(因此C++标准委员会认为它对于显式(C++ 17风格)矢量化是必要的)?
parallel-processing simd vectorization auto-vectorization c++17
我的(相当大的)C ++项目已经发展到C1060: compiler is out of heap space在尝试编译项目时出现错误的地步。
我正在64位Windows 10机器上进行编译,但似乎Visual Studio正在使用32位工具集来编译我的项目(请参见下面的屏幕截图)。
该C1060帮助页面要求我使用64位的工具集,但提供的链接了解如何只用命令行编译时启用了会谈。
是否可以在Visual Studio 2017中设置项目属性或其他方式来告诉它使用64位编译器工具集(已安装在我的计算机上)?
我正在实现一个算法,为了保持所需的时间复杂度,我想在移动Vec时保存一个指向元素的指针。Vec
具体来说,是这样的:
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3];
let ptr: *mut usize = &mut v[1] as *mut usize;
let mut u: Vec<usize> = v;
assert!(ptr == &mut u[1] as *mut usize);
println!("{}", unsafe { *ptr });
}
Run Code Online (Sandbox Code Playgroud)
实际的代码更复杂,涉及树状数据结构,其中每个顶点拥有一个Vec子节点。我在这里不是在问编码风格,但我的问题是是否可以依赖这段代码来完成我认为它所做的事情。
由于Vec必须将其内容保存在堆上,并且移动相当于memcpyRust,我认为可移动的事实Vec意味着我的代码是健全的(即不是未定义的行为)。它是否正确?
我可以使用第一个参数作为第二个参数的默认值,像这样吗?
int do_something(int a, int b = a + 1){
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
我的编译器似乎不喜欢它,所以也许它是不允许的.
在下面的代码中,x由于原子线程围栏,线程2中的值将始终为10.
int x;
atomic<bool> b(false);
// thread 1:
x = 10;
atomic_thread_fence(memory_order_release);
b = true;
// thread 2:
while(!b){}
atomic_thread_fence(memory_order_acquire);
assert(x == 10); // x will always be 10
Run Code Online (Sandbox Code Playgroud)
但是在下面的代码中,*x线程2中的总是10?
int* x = new int;
atomic<bool> b(false);
// thread 1:
*x = 10;
atomic_thread_fence(memory_order_release);
b = true;
// thread 2:
while(!b){}
atomic_thread_fence(memory_order_acquire);
assert(*x == 10); // will *x always be 10?
Run Code Online (Sandbox Code Playgroud) 通常,我会std::string从函数返回a ,因为返回a const char*将要求调用者提供输出内存缓冲区,并且该缓冲区不可调整大小.
但是const char*从字符串文字返回一个有效的if?
const char* generate_c_string() {
return "ABC";
}
Run Code Online (Sandbox Code Playgroud)
这样做(如果有效)可能会更快,因为我不需要动态分配内存来构造一个std::string.
它可能是有效的,因为它const char* x = "ABC";是有效的.是否有来自C++标准的参考资料证实其有效性?