我有一个指针,ptr和一个条件,cond.我需要最快的方式重置ptr如果cond是true,还是保留ptr,如果不变cond的false.目前的实施是简单的:
void reset_if_true(void*& ptr, bool cond)
{
if (cond)
ptr = nullptr;
}
Run Code Online (Sandbox Code Playgroud)
我知道上面的代码性能很好,我不能指望优化它的主要性能提升.但是,这段代码每秒被调用数百万次,并且保存的每个小纳秒都是相关的.
我正在考虑摆脱分支的事情,例如:
void* p[] = { ptr, nullptr };
ptr = p[cond];
Run Code Online (Sandbox Code Playgroud)
但我不确定这是最好的办法.
假设我们有2个常数A&B和一个变量i,所有64位整数.我们想要计算一个简单的通用算术运算,例如:
i * A / B (1)
Run Code Online (Sandbox Code Playgroud)
为了简化问题,我们假设变量i总是在范围内[INT64_MIN*B/A, INT64_MAX*B/A],因此算术运算(1)的最终结果不会溢出(即:适合该范围[INT64_MIN, INT64_MAX]).
另外,i假设更有可能在友好范围Range1 = [INT64_MIN/A, INT64_MAX/A](即:接近0),但是i可能(不太可能)在该范围之外.在第一种情况下,一个平凡的整数计算i * A不会溢出(这就是我们称之为范围友好的原因); 并且在后一种情况下,i * A将会溢出的平凡整数计算,导致(1)的计算中的错误结果.
什么是"最安全"和"最有效"的计算操作方法(1)(其中"最安全"意味着:保持准确性或至少相当精确,"最有效"意味着:最低平均计算时间),提供i更有可能在友谊范围Range1.
目前,代码中当前实现的解决方案如下:
(int64_t)((double)A / B * i)
Run Code Online (Sandbox Code Playgroud)
哪个解决方案非常安全(没有溢出)虽然不准确(由于双重有效位和53位限制导致的精度损失)并且非常快,因为(double)A / B在编译时预分配了双重除法,只允许在运行时计算双乘法.
我有以下模板类:
template<class I>
class T : public I
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
对于给定的模板参数,此模板类需要一次(且仅一次)派生I.
class A : public T<U> {}; // ok
class B : public T<V> {}; // ok
class C : public T<U> {}; // compile error
Run Code Online (Sandbox Code Playgroud)
模板类T可以适合于实现这样的行为(而类A,B,U,V不能); 但是,T决不能有关于派生类的任何知识A,B,C.
有没有办法防止这样的模板类被多次派生?理想情况下,在这种情况下发出编译错误,或者至少是链接器错误.
当一个类有一个简单的构造函数和/或一个普通的析构函数时,C++标准定义了一些非常具体的行为.
例如,根据标准的§3.8/ 1:
类型对象的生命周期在以下情况
T结束:- 如果
T是具有非平凡析构函数(12.4)的类类型,则析构函数调用将启动,或者- 重用或释放对象占用的存储空间.
所以,
虽然这个例子可能不是最好的例子,但它表明行为的差异可能是至关重要的(UB /非UB),无论一个对象是否具有琐事可破坏性.
标准的第12.4/3条规定,T如果一个类的析构函数是隐含的,而不是虚拟的,并且如果所有基类和类的成员T都是可以轻易破坏的,那么(对于sumezeze)类的析构函数是微不足道的.
在我的(适度)体验中,我从未在编译器生成的代码方面看到任何区别:
所以,我的问题是:
我的问题与标准无关(请不要回答标准陈述什么是微不足道的ctor/dtor,所以用户定义的ctor/dtor不是)但是编译器处理用户定义的ctor/dtor的方式以及以何种方式与普通的ctor/dtor相比,编译代码的行为可能会改变(或不改变).
我需要检查一个类C是否有一个默认的构造函数,无论是隐式的还是自定义的,或者是public,protected或者private.
我尝试使用std::is_default_constructible<C>::value,如果返回真C有一个public默认的构造函数(隐式或自定义),但false如果C有一个protected或private默认的构造函数(接缝是标准的行为虽然).
有没有办法检查一个类是否有一个protected或private默认的构造函数?
注意(如果这可能有帮助):检查是从要检查friend的类的函数执行的C.
我需要执行此检查,以便默认构造对应于元组nullptr指针的对象,对象的m_objs成员Foo(下面的部分Foo定义):
template<class... Objects>
class Foo
{
public:
Foo(Objects*... objects)
: m_objs(objects...)
{
// User construct a Foo objects passing a pack of pointers
// some of them are nullptr, some are not.
// The following call should default-construct objects corresponding …Run Code Online (Sandbox Code Playgroud) 我有一个模板功能,func:
template<typename T>
void func(T p) { f(p); }
Run Code Online (Sandbox Code Playgroud)
还有一套功能f:
f(SomeType&);
f(int);
...
Run Code Online (Sandbox Code Playgroud)
如果我实例化模板函数,func使用引用作为函数参数p,而不显式指定模板参数T,那么推导出的类型将不是引用类型p,而是类型p是对它的引用,例如:
SomeType s;
SomeType& ref_to_s = s;
func(ref_to_s); // Type deduction results in: func<SomeType>(ref_to_s)
func<SomeType&>(ref_to_s); // Need to explicitly specify type to work with reference
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:
SomeType&在上述情况下无法推断出引用类型?func,因此类型推导与引用类型一起使用,而没有明确指定模板参数T?要清楚,我想要两者兼顾(参见f上面的函数):
func(ref_to_s); // Calls func<SomeType&>(ref_to_s)
func(1); // Calls func<int>(1)
Run Code Online (Sandbox Code Playgroud) 假设我定义了一个T使用模板参数的嵌套类的模板P,如下所示:
template<class P> class T
{
public:
T(P& p) : p(p) {}
P& p;
typename P::Nested& get_nested() { return p.nested; }
};
Run Code Online (Sandbox Code Playgroud)
如果我声明一个A包含一个名为的嵌套类的类Nested,我可以定义一个T<A>没有问题的类型的变量:
class A
{
public:
class Nested
{
public:
int i;
};
Nested nested;
};
void test2a()
{
A a;
a.nested.i = 1;
T<A> t_a(a);
t_a.get_nested().i = 2;
}
Run Code Online (Sandbox Code Playgroud)
现在,我想声明一个类B,以同样的方式,包含一个名为的嵌套类,Nested并继承自T<B>,如下所示:
class B : public T<B>
{
public:
class Nested
{
public:
int …Run Code Online (Sandbox Code Playgroud) 我现在正在设计我自己的带有邻接列表的图形类.除了析构函数之外,我完成了大部分步骤.
这是我的Vertex类:
struct Vertex{
public:
Vertex(){m_name="";}
Vertex(string name):m_name(name){}
~Vertex(){
cout << "vertex des" << endl;
for(int i = 0; i < m_edge.size(); i++){
delete m_edge[i];
m_edge[i] = nullptr;
}
}
string m_name;
vector<Edge*> m_edge;
};
Run Code Online (Sandbox Code Playgroud)
这是我的Edge类:
struct Edge{
public:
Edge() : m_head(nullptr), m_tail(nullptr) {m_name="";}
Edge(string name) : m_name(name), m_head(nullptr), m_tail(nullptr) {}
~Edge(){
cout << "Edge des" << endl;
delete m_head;
m_head = nullptr;
delete m_tail;
m_tail = nullptr;
}
string m_name;
Vertex* m_head;
Vertex* m_tail;
};
Run Code Online (Sandbox Code Playgroud)
但是,我注意到在调用析构函数时,两个类实际上都调用了彼此的析构函数,因此这给了我一个无限循环.这个设计有问题吗?如果没有,有没有办法解决这个析构函数问题?谢谢!
我有一组使用成员typedef链接的类,Next如下所示:
class Y; class Z;
class X { public: typedef Y Next; };
class Y { public: typedef Z Next; };
class Z { };
Run Code Online (Sandbox Code Playgroud)
我需要一种方法来获得链的最终类,从链的任何类开始.感谢这篇文章的接受答案,我写了以下代码:
// cond_type<Condition, Then, Else>::type // selects type 'Then' if 'Condition' is true, or type 'Else' otherwise
template <bool Condition, typename Then, typename Else = void>
struct cond_type
{
typedef Then type;
};
template <typename Then, typename Else>
struct cond_type<false, Then, Else >
{
typedef Else type;
};
template …Run Code Online (Sandbox Code Playgroud) 以下部分模板类专业化的基本示例,取自此 wiki 页面:
template <typename Key, typename Value>
class KeyValuePair { /* something generic */ };
template <typename Key>
class KeyValuePair<Key, bool> { /* something specific to Value=bool */ };
KeyValuePair<int> kvpi;
Run Code Online (Sandbox Code Playgroud)
生成编译器错误:
prog.cpp:10:17: error: wrong number of template arguments (1, should be 2) KeyValuePair<int> kvpi;
Run Code Online (Sandbox Code Playgroud)
为什么 ?我究竟做错了什么 ?应如何声明和实例化部分模板类特化?
我期望变量kvpi是 type 的部分专用模板类实例KeyValuePair<int,bool>。
c++ ×10
c++11 ×4
templates ×4
c++14 ×3
c ×1
constructor ×1
destructor ×1
graph ×1
inheritance ×1
oop ×1
optimization ×1
sfinae ×1