标签: effective-c++

C++:使用const和STL迭代器

Effective C++,第3项

/* case1 */ const std::vector<int>::iterator i  // i  acts like a T* const
/* case2 */ std::vector<int>::const_iterator ci // ci acts like a const T*
Run Code Online (Sandbox Code Playgroud)

为了记住如何const应用,我曾经记得本文中的以下内容

基本上'const'适用于其左边的任何东西(除非没有任何东西,在这种情况下它适用于它的直接权利).

当我第一次阅读本书中的第3项时,我预计它将在case1和case2中反过来.

我应该把这个案子当作例外吗?或者是否有一些我缺失的更深层次的理解?

c++ templates stl const effective-c++

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

有效的c ++第3项示例

我的问题是关于"Effective C++"一书的特定项目(3).本书给出了这个例子,我尝试尽可能接近vs 2010 c ++(包括iostream和string):

class TextBlock {
public: 
    const char& operator[](std::size_t pos) const
    {
        return text[pos]; 
    }
    char& operator[](std::size_t pos)
    { 
        return text[pos]; 
    }

private: 
    std::string text;
};

void print(const TextBlock& ctb)
{
    std::cout << ctb[0]; // OK
    //ctb[0] = ‘A’; // Not OK – compiler error
}

int _tmain(int argc, _TCHAR* argv[])
{
    TextBlock tb(“Hello”);
    std::cout << tb[0];
    tb[0] = ‘x’; // OK because return has &, not const
    const TextBlock ctb("World");
    std::cout << ctb[0];
    return 0;
} …
Run Code Online (Sandbox Code Playgroud)

c++ effective-c++

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

在正确实现 Scott Meyer 的更有效的 C++ 第 22 条:“考虑使用 op= 而不是独立 op”时避免通用引用?

我正在尝试遵循 Scott Meyers 在更有效的 C++ 第 22 条中的建议:“考虑使用op=而不是独立op”。他建议我们可以创建一个模板operator+,以便所有实现的类operator+=自动获得operator+

template<class T>
const T operator+(const T& lhs, const T& rhs)
{ 
    return T(lhs) += rhs; 
}
Run Code Online (Sandbox Code Playgroud)

现在,在《Effective Modern C++》第 25 条中,有一个矩阵加法的示例(第 172 页),其中operator+建议使用右值重载 ,因为如果您知道lhsrhs是右值,则可以使用它们来存储结果,从而防止可能巨大的矩阵的无用副本。所以我添加了重载:

template<class T>
T operator+(T&& lhs, const T& rhs)
{ 
    return std::move(lhs += rhs);
}

template<class T>
T operator+(T const& lhs, T&& rhs)
{ 
    return std::move(rhs += lhs);
}

template<class T>
T operator+(T&& …
Run Code Online (Sandbox Code Playgroud)

c++ templates operator-overloading effective-c++ overload-resolution

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

尾随返回类型和右值

我正在阅读Scott Meyers的Effective Modern C++,我在我的机器上尝试了他为Deducing Types章节提供的示例.

他提供这个功能:

template <typename Container, typename Index>
auto decltype_test_1(Container& c, Index i) -> decltype(c[i])
{
  return c[i];
}
Run Code Online (Sandbox Code Playgroud)

然后它以这种方式使用该功能:

std::deque<int> d;
…
decltype_test_1(d, 5) = 10; // authenticate user, return d[5],
                          // then assign 10 to it;
                          // this won't compile!
Run Code Online (Sandbox Code Playgroud)

说它不会编译.我试过MSVC,它确实编译.我写了以下内容main:

std::deque<int> d;
d.push_back(0);
d.push_back(1);
d.push_back(2);

decltype_test_1(d, 0) = 10;

for each (auto item in d)
  cout << item << endl;
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它编译,最重要的是,它显示10为双端队列的第一个元素.他解释说这个代码是错误的.它为什么在这里工作?我错过了什么?

c++ decltype effective-c++ c++11

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

strncpy/memcpy/memmove 是否逐字节或以其他有效方式复制数据?

众所周知,在 x86/x86_64 等多字节字计算机中,逐字复制/移动大量内存(每步 4 或 8 个字节)比逐字节复制/移动更有效。

我很好奇 strncpy/memcpy/memmove 会以哪种方式做事,以及它们如何处理内存字对齐。

char buf_A[8], buf_B[8];

// I often want to code as this
*(double*)buf_A = *(double*)buf_B;

//in stead of this
strcpy(buf_A, buf_B);
// but it worsen the readability of my codes.
Run Code Online (Sandbox Code Playgroud)

memcpy effective-c++ strcpy strncpy memmove

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

使用"Uncopyable"类时,会消除GCC警告

我有几个我不想复制的类,其中一些类有指针数据成员.为了使这些类不可复制,我私下继承了以下类模板:

template <class T>
class Uncopyable
{
  protected:
    Uncopyable() {}
    virtual ~Uncopyable() {}
  private:
    Uncopyable(const Uncopyable &);
    T & operator=(const T&);
};
Run Code Online (Sandbox Code Playgroud)

我这样使用的是:

class Entity : private Uncopyable<Entity> { }
Run Code Online (Sandbox Code Playgroud)

这工作正常,但是当我使用-Weffc ++编译时,我仍然收到以下警告:

class Entity has pointer data members
but does not override Entity(const Entity&)
or operator=(const Entity&)
Run Code Online (Sandbox Code Playgroud)

为什么它仍然给我这个警告?

c++ effective-c++

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

在C++中返回局部变量(Effective C++,3rd edition中的Rule 21)

众所周知,由于作用域,从C++中的函数返回局部变量是不安全的.在Effective C++第三版中,Scott Meyers在第21页的第21项中讲述了这个问题.然而,最后他说,正确的决定将是:

inline const Rational operator*(const Rational& lhs, const Rational& rhs) {
    return Rational(lhs.n * rhs.h, lhs.d * rhs.d);
}
Run Code Online (Sandbox Code Playgroud)

这不是一个坏习惯,这个功能不安全吗?

UPD:谢谢大家的解释.

c++ return local effective-c++

0
推荐指数
2
解决办法
298
查看次数

有效的C++ Item 11处理对self的赋值

我正在读这本书,我不明白两段代码之间的区别.

class Bitmap{...};
class Widget
{
    ...
private:
    Bitmap* m_pb;
};

Widget& Widget::operator=(const Widget& rhs)
    {
        if (this == &rhs)
        {
            return *this;  // if a self-assignment, do nothing
        }
        delete pb;
        pb = new Bitmap(*rhs.m_pb);
        return *this;
    }
Run Code Online (Sandbox Code Playgroud)

迈尔斯先生说:

如果"new Bitmap"表达式产生异常,则Widget将最终保持指向已删除Bitmap的指针.

这是否意味着pd指针指向NULL?

Widget& Widget::operator=(const Widget& rhs)
{
    Bitmap* temp = pb;
    pb = new Bitmap(*rhs.pb);
    delete temp;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

迈尔斯先生说:

现在,如果"new Bitmap"抛出异常,pb指针保持不变.

据我所知,临时指针指向与pb指针相同的内存地址.如果"new"抛出异常,pb将指向NULL,下一句将删除Bitmap.那是对的吗?我没有看到这些实现之间的区别.

提前致谢.

c++ effective-c++

0
推荐指数
1
解决办法
213
查看次数