我只是看着Stephan T. Lavavej谈论CppCon 2018"课程模板论证演绎",他在某些时候偶然说:
在C++类型中,信息几乎从不向后流动...... 我不得不说"差不多",因为有一两个案例,可能更多但很少.
尽管试图找出他可能指的是哪些案件,但我无法想出任何建议.因此问题是:
在哪些情况下,C++ 17标准要求类型信息向后传播?
浏览标准草案(n3242)我在第9.2条(强调我的)中找到了这句话:
非静态(9.4)数据成员不应具有不完整类型.特别是,类C不应包含类C的非静态成员,但它可以包含指向C类对象的指针或引用.
从这里我认为可以定义这样的类:
class A {
public:
A(A& a) : a_(a){
}
private:
A& a_;
};
Run Code Online (Sandbox Code Playgroud)
然后在第8.3.2节中我发现了以下内容:
应初始化引用以引用有效的对象或函数
问题1:是否允许定义此类型的对象,并将其名称作为参考:
A a(a);
Run Code Online (Sandbox Code Playgroud)
或者这会触发未定义的行为?
问题2:如果是,标准的哪些部分允许从仍待构建的对象初始化引用?
问题3:如果不是,这是否意味着A类的定义形式良好但是没有触发UB就不能创建第一个对象?在这种情况下,这背后的理由是什么?
我碰巧有几次将部分程序与OpenMP并行化,只是为了注意到最终,尽管具有良好的可扩展性,但由于单线程情况的性能较差,大多数预见的加速都会丢失(如果与串行版).
网络上出现的这种行为的常见解释是编译器生成的代码在多线程情况下可能更糟糕.无论如何,我无法在任何地方找到解释为什么装配可能更糟的参考.
那么,我想问问编译器的人是:
多线程可以抑制编译器优化吗?万一,性能怎么会受到影响?
如果它可以帮助缩小问题,我主要对高性能计算感兴趣.
免责声明:正如评论中所述,以下部分答案可能在将来过时,因为它们简要讨论了在提出问题时编译器处理优化的方式.
在这个问题中讨论了为什么暴露私有类型auto:
#include <iostream>
using namespace std;
class Base {
class PrivateClass {
public:
void bar() { cout << "PrivateClass" << endl; }
};
public:
PrivateClass foo() {
PrivateClass a;
return a;
}
};
int main() {
Base b;
auto p = b.foo();
p.bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C++ 11标准完全没问题.我还没有得到的是这个成语在实际应用中如何有用. 是否有问题可以有效地使用这个成语,或者它应该被视为关键词的"好奇"副作用?
模板类中的许多方法都vector接受value_type对象的const引用,例如:
void push_back (const value_type& val);
Run Code Online (Sandbox Code Playgroud)
while 按值resize获取其value_type参数:
void resize (size_type n, value_type val = value_type());
Run Code Online (Sandbox Code Playgroud)
作为一个非专业的C++程序员,我只能想到这个选择的缺点(例如,如果size_of(value_type)可能发生足够大的堆栈溢出).因此,我想对那些对语言有更深入了解的人提出这样的要求:
这个选择背后的设计理由是什么?
我在这里提出的问题之后问这个问题.
这一点非常简单.假设你有两类这样的类:
template < class Derived >
class Base {
...
operator const Derived&() const {
return static_cast< const Derived& >(*this);
}
...
};
class Specialization : public Base<Specialization> {
...
};
Run Code Online (Sandbox Code Playgroud)
然后假设您有类似这样的类型转换:
template < class T >
functionCall( const Base<T>& param) {
const T & val(param);
...
}
Run Code Online (Sandbox Code Playgroud)
问题是:这种转换的标准符合行为应该是什么?
它是否应该相同const T & val(static_cast<const T &> (param) )或应该递归迭代直到堆栈溢出?请注意,我获得了第一个使用GNU编译的行为g++,第二个使用Intel编译icpc.
我已经试图查看标准(关于static_cast的第5.9节和关于转换的第12.3节),但由于我缺乏经验,我无法找到答案.
我非常感谢任何花时间帮助我解决这个问题的人.
几天前,我偶然发现了一个代码,其中广泛使用从指针到类型到指针到类型数组的转换,以给出内存中线性向量的二维视图.为清楚起见,下面报告了这种技术的一个简单例子:
#include <stdio.h>
#include <stdlib.h>
void print_matrix(const unsigned int nrows, const unsigned int ncols, double (*A)[ncols]) {
// Here I can access memory using A[ii][jj]
// instead of A[ii*ncols + jj]
for(int ii = 0; ii < nrows; ii++) {
for(int jj = 0; jj < ncols; jj++)
printf("%4.4g",A[ii][jj]);
printf("\n");
}
}
int main() {
const unsigned int nrows = 10;
const unsigned int ncols = 20;
// Here I allocate a portion of memory to …Run Code Online (Sandbox Code Playgroud) 在使用CMake的Linux下,我正在构建一个共享库libIex-2_0.so.10.0.1
ADD_LIBRARY (Iex SHARED
[*.cpp]
)
SET_TARGET_PROPERTIES(Iex PROPERTIES OUTPUT_NAME "Iex-2_0")
Run Code Online (Sandbox Code Playgroud)
10.0.1版本设置为调用
SET_TARGET_PROPERTIES ( Iex
PROPERTIES
VERSION 10.0.1
SOVERSION 10
)
Run Code Online (Sandbox Code Playgroud)
在安装文件夹中,将创建这些链接
libIex-2_0.so -> libIex-2_0.so.10
libIex-2_0.so.10 -> libIex-2_0.so.10.0.1
libIex-2_0.so.10.0.1
Run Code Online (Sandbox Code Playgroud)
但是,要匹配以前使用其他构建系统构建的构建,我需要添加旧的符号链接,剥离2_0后缀:
libIex.so -> libIex-2_0.so.10.0.1
Run Code Online (Sandbox Code Playgroud)
创建这样一个链接的CMake方法是什么?
在实现工厂类时,我遇到了std::auto_ptr一些我无法理解的行为.我将问题减少到下面的小程序,所以......让我们开始吧.
考虑以下单例类:
singleton.h
#ifndef SINGLETON_H_
#define SINGLETON_H_
#include<iostream>
#include<memory>
class singleton {
public:
static singleton* get() {
std::cout << "singleton::get()" << std::endl;
if ( !ptr_.get() ) {
std::cout << &ptr_ << std::endl;
ptr_.reset( new singleton );
std::cout << "CREATED" << std::endl;
}
return ptr_.get();
}
~singleton(){
std::cout << "DELETED" << std::endl;
}
private:
singleton() {}
singleton(const singleton&){}
static std::auto_ptr< singleton > ptr_;
//static std::unique_ptr< singleton > ptr_;
};
#endif
Run Code Online (Sandbox Code Playgroud)
singleton.cpp
#include<singleton.h>o
std::auto_ptr< singleton > singleton::ptr_(0);
//std::unique_ptr< singleton > …Run Code Online (Sandbox Code Playgroud) 消息传递接口 API 始终用作变量int的类型count。例如,原型是MPI_Send:
int MPI_Send(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);
Run Code Online (Sandbox Code Playgroud)
如果要发送或接收的元素数量接近甚至超过 INT_MAX,这可能会成为问题。
当然,可以通过以下任一方法降低 的值来解决该问题count:
MPI_Datatype无论如何,这两种方法都更像是一种黑客行为,而不是真正的解决方案,特别是如果使用简单的启发式方法来实现。因此我想问的是:
是否有更好的习惯用标准 MPI 调用来处理此类情况?如果没有,有人知道一些围绕 MPI 构建的(实体)包装库来克服这个限制吗?