小编shr*_*ike的帖子

在条件上更新变量的最快方法是什么?

我有一个指针,ptr和一个条件,cond.我需要最快的方式重置ptr如果condtrue,还是保留ptr,如果不变condfalse.目前的实施是简单的:

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)

但我不确定这是最好的办法.

c++ optimization

55
推荐指数
4
解决办法
3835
查看次数

计算可能溢出的整数运算的最安全,最有效的方法

假设我们有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在编译时预分配了双重除法,只允许在运行时计算双乘法.

c c++

25
推荐指数
2
解决办法
630
查看次数

如何防止模板类被多次派生?

我有以下模板类:

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++ inheritance templates

19
推荐指数
2
解决办法
1012
查看次数

一个普通的ctor(或dtor)和一个用户定义的空ctor(或dtor)之间有什么区别

当一个类有一个简单的构造函数和/或一个普通的析构函数时,C++标准定义了一些非常具体的行为.

例如,根据标准的§3.8/ 1:

类型对象的生命周期在以下情况T结束:

- 如果T是具有非平凡析构函数(12.4)的类类型,则析构函数调用将启动,或者

- 重用或释放对象占用的存储空间.

所以,

  • 如果一个对象不是可以破坏的,那么在调用析构函数之后访问该对象成员的任何尝试都是UB.
  • 如果一个对象是琐事可破坏的,那么在调用析构函数之后尝试访问该对象的成员是安全的而不是UB.

虽然这个例子可能不是最好的例子,但它表明行为的差异可能是至关重要的(UB /非UB),无论一个对象是否具有琐事可破坏性.

标准的第12.4/3条规定,T如果一个类的析构函数是隐含的,而不是虚拟的,并且如果所有基类和类的成员T都是可以轻易破坏的,那么(对于sumezeze)类的析构函数是微不足道的.

在我的(适度)体验中,我从未在编译器生成的代码方面看到任何区别:

  • 一个有一个普通的默认ctor和/或一个普通的dtor的类,和
  • 具有用户定义的空 ctor和/或非虚拟用户定义的空 dtor的类(只要该类,其基类和成员类也具有非虚拟dtor用户定义的空或平凡)

所以,我的问题是:

  • 以何种方式,用户定义的空ctor/dtor可以或不可以被视为关于编译器代码生成,优化,权衡,...的简单类似的ctor/dtor.
  • 与用户定义的非空ctor/dtor相同的问题; 什么规则应遵循ctor/dtor中实现的代码来将它们视为微不足道的.

我的问题与标准无关(请不要回答标准陈述什么是微不足道的ctor/dtor,所以用户定义的ctor/dtor不是)但是编译器处理用户定义的ctor/dtor的方式以及以何种方式与普通的ctor/dtor相比,编译代码的行为可能会改变(或不改变).

c++ constructor destructor

11
推荐指数
1
解决办法
4340
查看次数

如何检查类是否具有默认构造函数(public,protected或private)

我需要检查一个类C是否有一个默认的构造函数,无论是隐式的还是自定义的,或者是public,protected或者private.

我尝试使用std::is_default_constructible<C>::value,如果返回真C有一个public默认的构造函数(隐式或自定义),但false如果C有一个protectedprivate默认的构造函数(接缝是标准的行为虽然).

有没有办法检查一个类是否有一个protectedprivate默认的构造函数?

注意(如果这可能有帮助):检查是从要检查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)

c++ c++11 c++14

8
推荐指数
1
解决办法
2016
查看次数

如何使用引用使模板类型推导工作?

我有一个模板功能,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)

c++ templates c++11 c++14

7
推荐指数
2
解决办法
1004
查看次数

在CRTP中使用嵌套的模板参数类

假设我定义了一个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)

c++

5
推荐指数
2
解决办法
390
查看次数

循环数据依赖析构函数

我现在正在设计我自己的带有邻接列表的图形类.除了析构函数之外,我完成了大部分步骤.

这是我的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)

但是,我注意到在调用析构函数时,两个类实际上都调用了彼此的析构函数,因此这给了我一个无限循环.这个设计有问题吗?如果没有,有没有办法解决这个析构函数问题?谢谢!

c++ oop graph c++11

5
推荐指数
1
解决办法
179
查看次数

检查类是否在继承层次结构中明确定义成员类型

我有一组使用成员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)

c++ templates sfinae c++11 c++14

5
推荐指数
1
解决办法
370
查看次数

模板类偏特化语法

以下部分模板类专业化的基本示例,取自此 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++ templates

3
推荐指数
2
解决办法
3034
查看次数

标签 统计

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