小编YSC*_*YSC的帖子

在C++中,我是否应该费心缓存变量,还是让编译器进行优化?(混叠)

请考虑以下代码(p属于类型unsigned char*bitmap->width属于某种整数类型,具体哪个是未知的,取决于我们正在使用的某个外部库的版本):

for (unsigned x = 0;  x < static_cast<unsigned>(bitmap->width);  ++x)
{
    *p++ = 0xAA;
    *p++ = 0xBB;
    *p++ = 0xCC;
}
Run Code Online (Sandbox Code Playgroud)

值得优化它[...]

可能存在这样一种情况,即通过编写可以产生更有效的结果:

unsigned width(static_cast<unsigned>(bitmap->width));
for (unsigned x = 0;  x < width;  ++x)
{
    *p++ = 0xAA;
    *p++ = 0xBB;
    *p++ = 0xCC;
}
Run Code Online (Sandbox Code Playgroud)

...或者编译器优化是否微不足道?

您认为什么是"更好"的代码?

编辑(Ike)的注意事项:对于那些对三角形文本感到疑惑的人来说,原来的问题,如同措辞一样,非常接近于偏离主题的领域,并且尽管有积极的反馈,但非常接近于被关闭.这些已经被打乱了.但是,请不要惩罚那些解决这些问题的受影响部分的回答者.

c++ optimization performance caching strict-aliasing

114
推荐指数
9
解决办法
7276
查看次数

未使用的成员变量会占用内存吗?

初始化成员变量而不引用或使用它会在运行时进一步占用RAM,还是编译器只是忽略该变量?

struct Foo {
    int var1;
    int var2;

    Foo() { var1 = 5; std::cout << var1; }
};
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,成员'var1'得到一个值,该值然后显示在控制台中。但是,根本不使用“ Var2”。因此,在运行时将其写入内存将浪费资源。编译器会考虑这种情况,而只是忽略未使用的变量,还是Foo对象总是相同大小,而不管是否使用其成员?

c++ memory struct

88
推荐指数
5
解决办法
6891
查看次数

在派生类中具有相同名称但签名不同的函数

我有一个具有相同名称的函数,但在基类和派生类中具有不同的签名.当我尝试在继承自派生的另一个类中使用基类的函数时,我收到一个错误.请参阅以下代码:

class A
{
    public:
    void foo(string s){};
};

class B : public A
{
    public:
    int foo(int i){};
};

class C : public B
{
    public:
    void bar()
    {
        string s;
        foo(s);
    }
};
Run Code Online (Sandbox Code Playgroud)

我从gcc编译器收到以下错误:

In member function `void C::bar()': no matching function for call to `C::foo(std::string&)' candidates are: int B::foo(int)
Run Code Online (Sandbox Code Playgroud)

如果我int foo(int i){};从课堂上删除B,或者我将其重命名foo1,一切正常.

这有什么问题?

c++ lookup inheritance function c++-faq

83
推荐指数
2
解决办法
4万
查看次数

通过成员指针访问受保护的成员:这是一个黑客?

我们都知道protected从基类指定的成员只能从派生类自己的实例访问.这是标准的一个特性,这已在Stack Overflow上多次讨论:

但似乎有可能用成员指针来解决这个限制,因为用户chtz 向我展示:

struct Base { protected: int value; };
struct Derived : Base
{
    void f(Base const& other)
    {
        //int n = other.value; // error: 'int Base::value' is protected within this context
        int n = other.*(&Derived::value); // ok??? why?
        (void) n;
    }
};
Run Code Online (Sandbox Code Playgroud)

coliru现场演示

为什么这可能,它是一个想要的功能或实施中的某个地方或标准的措辞?


从评论中出现了另一个问题:如果Derived::f用实际调用Base,是不确定的行为?

c++ protected access-specifier member-pointers language-lawyer

52
推荐指数
2
解决办法
3777
查看次数

这个浮点平方根逼近是如何工作的?

我找到了一个相当奇怪但工作的平方根逼近floats; 我真的不明白.有人能解释一下为什么这段代码有效吗?

float sqrt(float f)
{
    const int result = 0x1fbb4000 + (*(int*)&f >> 1);
    return *(float*)&result;   
}
Run Code Online (Sandbox Code Playgroud)

我测试了一下它输出的值std::sqrt()约为1到3%.我知道Quake III的快速反平方根,我想这里有类似的东西(没有牛顿迭代),但我真的很感激它的工作原理.

(nota:我已经用标记了它,因为它既有效-ish(见注释)C和C++代码)

c c++ floating-point optimization ieee-754

51
推荐指数
4
解决办法
3759
查看次数

使一个函数接受一个可选的接受非可选的?

我正在尝试以monad风格编写语法糖std::optional.请考虑:

template<class T>
void f(std::optional<T>)
{}
Run Code Online (Sandbox Code Playgroud)

即使存在从22的转换,也不能使用非可选T1(例如an int)调用此函数.Tstd::optional<T>

有没有办法f接受a std::optional<T>或a T(在调用者站点转换为可选),而没有定义过载3


1) f(0):error: no matching function for call to 'f(int)'note: template argument deduction/substitution failed,(演示).
2)因为模板参数推导不考虑转换.
3)超载是用于一个一元函数的可接受的解决方案,但开始是当你有像二进制功能的烦恼operator+(optional, optional),并且是用于三元疼痛,4元,等等功能.

c++ templates optional template-argument-deduction c++17

47
推荐指数
4
解决办法
2765
查看次数

错误的演员表 - 是演员表或使用未定义的行为

如果我从Base转换为Derived类型,但Base类型不是派生类型的实例,但只使用结果,是否会得到未定义的行为?

很难理解我在问什么?看看这个例子:

struct Animal { int GetType(){...} };
struct Dog : Animal { bool HasLoudBark(){...}};
struct Cat : Animal { bool HasEvilStare(){...} };

Animal * a = ...;
Dog* d = static_cast<Dog*>(a);

if(a->GetType() == DogType && d->HasLoudBark())
    ....
Run Code Online (Sandbox Code Playgroud)

在这种情况下a可能或不是Dog.我们总是做static_castaDog * d,但我们从来不使用d,除非我们确定它的一个Dog.

假设a不是a Dog,那么在演员阵容中这个未定义的行为是什么?或者它被定义为我们实际上没有使用,d除非它真的是一个Dog

赞赏参考标准的相关部分.

(是的,我知道我可以使用dynamic_cast和RTTI,可能这不是很好的代码,但我对这是否有效更感兴趣)

c++ casting undefined-behavior language-lawyer

36
推荐指数
2
解决办法
2037
查看次数

const对象传染媒介给编译错误

我在我的代码中声明了以下内容

vector <const A> mylist; 
Run Code Online (Sandbox Code Playgroud)

我得到以下编译错误 -

new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const \[with _Tp = const A]' and `_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const A]' cannot be overloaded
Run Code Online (Sandbox Code Playgroud)

但如果宣布 -

vector <A> mylist;
Run Code Online (Sandbox Code Playgroud)

我的代码编译.

在这种情况下不允许使用const吗?

我在这里复制我的代码供大家参考 -

#include <iostream>
#include <vector>

using namespace std;
class A
{
public:
    A () {cout << "default constructor\n";}
    A (int i): m(i) {cout << "non-default constructor\n";}

private:
    int m;
};

int main (void)
{
    vector<const A> mylist;

    mylist.push_back(1);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ stdvector c++98

35
推荐指数
2
解决办法
1万
查看次数

返回+重置成员变量最有效的方法?

什么是GetDeleteObjects下面实施的最有效的方式?

class Foo {
public:
  std::vector<Bar> GetDeleteObjects();
private:
  std::vector<Bar> objects_;
}

std::vector<Bar> Foo::GetDeleteObjects() {
  std::vector<Bar> result = objects_;
  objects_.clear();
  return result;
}
Run Code Online (Sandbox Code Playgroud)

目前,至少执行从objects_到result的副本.std::move例如,这可以更快地制作吗?

c++ copy move-semantics c++11

28
推荐指数
4
解决办法
1404
查看次数

ADL是调用朋友内联函数的唯一方法吗?

让我们在声明中定义f:作为朋友的函数:SS

struct S
{
    friend void f() {}
};
Run Code Online (Sandbox Code Playgroud)

我找不到打电话的方法f.

那么,这样的内联友元函数只能通过依赖参数的查找来调用吗?

struct S
{
    friend void f() {}
    friend void g(S const&) {}
} const s;

int main()
{
    // f();     // error: 'f' was not declared in this scope
    // S::f();  // error: 'f' is not a member of 'S'
    g(s);
    // S::g(s); // error: 'g' is not a member of 'S'
}
Run Code Online (Sandbox Code Playgroud)

额外奖励:如果我想获得函数指针/ std::function/ lambda g怎么办?

c++ friend language-lawyer name-lookup argument-dependent-lookup

24
推荐指数
2
解决办法
1027
查看次数