Coder Social home page Coder Social logo

discussion-for-cpp's Introduction

Discussion for C++

C++ 中文讨论区

question list0 list2 list3

discussion-for-cpp's People

Contributors

mooophy avatar pezy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

discussion-for-cpp's Issues

关于ex_7_06答案不应该和书上一致吧

题目是"对于函数add、read和print,定义你自己的版本"。
那么答案就不应该是前面书上已经给出的代码了,而且此时还没学到IO库应该写不出答案那样的代码啊?

关于lambda捕获this指针的问题

问题来源于C++Primer :Exercise 13.43:
for_each(elements, first_free, [this](std::string &rhs){ alloc.destroy(&rhs); });
我感到有点疑问。为什么不是捕获alloc,而是捕获this呢?

About Input

How can I read a sequence of ints from cin and store the values two vectors at the same time?like this,
vector val1,val2;
int i,j;
while(cin>>i) val1.push_back(i);
while(cin>>j) val2.push_back(j);

返回值的问题

一小段代码

#include <iostream>
#include <vector>
using std::vector;
int main()
{
    vector<int> iv={0,1,2,3,4};
    vector<int>::iterator iter=iv.begin(),mid=iv.begin()+iv.size()/2;
    int some_val=1;
    while(iter!=mid)
    {
        if(*mid==some_val)
        mid=iv.insert(mid,2*some_val);
        else --mid;
    }
    return 0;
}

运行时候返回值出问题了。
1

不知道问题出在哪里。感觉逻辑应该不错的。

A question about ex10.42

void elimDups(list<string> &words)
{
    words.sort();
    words.unique();
}

答案中用的是words.sort();//right,而不是sort(words.begin(), words.end());//wrong,是因为list的迭代器是双向迭代器,而不是随机访问迭代器,所以不支持<,<=,<=这样的关系运算符,所以不能这样sort(words.begin(), words.end());//wrong使用?

基于 C++ 模板的二分查找实现,错在哪里?

binary-search.h:

#ifndef BINARY_SEARCH_H_
#define BINARY_SEARCH_H_

#include <vector>

// Checks if an element equivalent to value appears within the range
// [first, last). There is std::binary_search exists, so do not use namespace
// std.
template <typename ForwardIterator, typename T>
bool BinarySearch(
    const ForwardIterator first,
    const ForwardIterator last,
    const T value);

namespace iteration {

template <typename ForwardIterator, typename T>
bool BinarySearch(
    ForwardIterator first,
    ForwardIterator last,
    const T value);

}  // namespace iteration

#endif  // BINARY_SEARCH_H_

binary-search.cc:

#include "binary-search.h"

#include <vector>

template <typename ForwardIterator, typename T>
bool BinarySearch(
    const ForwardIterator first,
    const ForwardIterator last,
    const T value) {
  if (first == last) return false;
  auto middle = first + (last - first) / 2;
  if (*middle == value) return true;
  if (*middle > value) return BinarySearch(first, middle, value);
  if (*middle < value) return BinarySearch(middle + 1, last, value);
}

namespace iteration {

template <typename ForwardIterator, typename T>
// first and last are not const.
bool BinarySearch(
    ForwardIterator first,
    ForwardIterator last,
    const T value) {
  ForwardIterator middle;
  while (first != last) {
    middle = first + (last - first) / 2;
    if (*middle == value) return true;
    if (*middle > value) last = middle;
    if (*middle < value) first = middle + 1;
  }
  return false;
}

}  // namespace iteration

search-test.cc:

// A simple test case, I will replace it with unittest framework in future.
#include "binary-search.h"

#include <cassert>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>

namespace {

constexpr int target = 100;  // value to search

}  // namespace

int main(void) {
  // You need to edit the file manually to test...
  std::ifstream input("sorted-int.txt");
  int num;
  std::vector<int> nums;
  while (input >> num)
    nums.push_back(num);
  input.close();
  assert(nums.size() > 0);
  assert(std::is_sorted(nums.begin(), nums.end()));
  // You can choose two implemetations.
  if (BinarySearch(nums.cbegin(), nums.cend(), target)) {
    // if (tail_recursion::BinarySearch(nums.cbegin(), nums.cend(), target)) {
    std::cout << "Find it." << std::endl;
  } else {
    std::cout << "No such one." << std:: endl;
  }
  return 0;
}

g++ binary-search.cc search-test.cc -std=c++11 出错:

/tmp/ccWIvgSc.o: In function main': search-test.cc:(.text+0x133): undefined reference tobool BinarySearch<__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator > >, int>(__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator > >, __gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator > >, int)'
collect2: error: ld returned 1 exit status

原本的 std::vector<int> 实现工作正常,但第一次用模板技术时编译失败,百思不解。

Maybe some bugs in ex10_34_35_36_37.cpp

 r_withOrdinary_print(v);//crash   my environment:win7+vs2013

2.少一个头文件vector
3.

inline void
r_print(const std::vector<std::string> &v)
{
    std::for_each(v.crbegin(), v.crend(), [](const std::string &s)
    {
        std::cout << s << " ";
    });
}
//建议改成
inline void
r_print(const std::vector<std::string> &v)
{
   copy(v.begin(),v.end(),std::ostream_iterator<string> (cout, " "));//这样写简洁一点
}

4.10.37题目说的是位置3到位置7, 所以这之间只有5个元素,而不是6个元素,至于位置3怎么理解,从0或1开始。

Exercise 7.35 问题

Exercise 7.35
Explain the following code, indicating which definition of Type or initVal is used for each use of those names. Say how you would fix any errors.

typedef string Type;
typedef string Type;
Type initVal();
class Exercise {
public:
    typedef double Type;
    Type setVal(Type);
    Type initVal();
private:
    int val;
};
Type Exercise::setVal(Type parm) {
    val = parm + initVal();
    return val;
}

有个疑问,为什么Type Exercise::setVal(Type parm) 中第一个Type是指typedef string Type
按照查找的原则不是先在成员函数内查找(此处未找到),然后在类内查找吗?(此处找到)

Exercise 7.49 (b) [proposed by dxiao6]

From 豆瓣讨论

dxiao6:
虽然再github上说得很明白了,但还是不理解 为什么加了const就能通过编译了.因为临时变量不能被绑定到普通引用上? 那为什么可以绑定到常量引用上呢?

6.46的答案不对吧?

isShorter函数不能定义成constexpr函数吧?isShorter函数返回值要调用size函数,编译时不能确定结果吧,测试了下不行。。。
答案不该是YES 应该是NO吧?

15.8.1 调用net_price虚函数

double Basket::total_receipt(ostream &os) const
{
    double sum = 0.0; // holds the running total
    // iter refers to the first element in a batch of elements with the same ISBN
    // upper_bound returns an iterator to the element just past the end of that batch
    for (auto iter = items.cbegin();
            iter != items.cend();
            iter = items.upper_bound(*iter)) {
        // we know there's at least one element with this key in the Basket
        // print the line item for this book
        sum += print_total(os, **iter, items.count(*iter));
    }
    os << "Total Sale: " << sum << endl; // print the final overall total
    return sum;
}

这里print_total会调用net_price虚函数. 按照书上的解释, 最终的price的计算结果取决于**item的dynamic type. 可是当我们调用add_item的时候, 相同的isbn(), 我们可能加入Quote type也可能会加入bulk_Quote type.

item是相同isbn()的batch的第一个元素. 那么我们怎么来判断item的dynamic type呢?

比如调用add_item的时候, 第一个加入的是Quote, 第二个是bulk_Quote, 第三个是Quote, 第四个是bulk_Quote...

c++primer中文版11.3.3

第一段最后一句说迭代器指定元素被删除,返回void
387页上方表11.5又说,删除迭代器指定元素返回最后被删除的元素的后一个元素迭代器
明显矛盾,前一个是旧标准,后一个是新标准?

Git 出问题了...

前些天配置了 git ,也 clone 了 Cpp-Primer 到本地仓库,看了下每个文件夹都有 n 个 cpp 文件,每个都有 mian 函数,感觉用 vs2013 来学习,太过了,就配置了个 Sublime Text 3 + MinGw 轻量级环境

default

配置好了后,发现 git 不能与远程仓库交互了出现的下面的问题:

default

google 后,说可能是 22 端口封了,换个就行,但换成 443 或 4443 都没成功,来请教下

@pezy @Mooophy 谢谢

vs2013 不支持 (*it).empty(); 或 it->empty(); ?

    string str(4, 'c');
    for (auto it = str.begin(); it != str.end(); ++it)
        if ((*it).empty())
            cout << *it << endl;

今天复习 string 时,想到的后面的迭代器,用了下结果有错误,想知道是我写错了?

Maybe some bugs in ex10_32.cpp

@pezy @Mooophy

int main()
{
    std::istream_iterator<Sales_item> in_iter(std::cin), in_eof;
    std::vector<Sales_item> vec;

    while (in_iter != in_eof)               //未执行,直接跳过
        vec.push_back(*in_iter++);
    sort(vec.begin(), vec.end(), compareIsbn);    //crash
    for (auto beg = vec.cbegin(), end = beg; beg != vec.cend(); beg = end) {
        end = find_if(beg, vec.cend(), [beg](const Sales_item &item){return item.isbn() != beg->isbn();});
        std::cout << std::accumulate(beg, end, Sales_item(beg->isbn())) << std::endl;
    }
}

    std::vector<Sales_item> vec;
    while (in_iter != in_eof)               //未执行,直接跳过
        vec.push_back(*in_iter++);

改成

std::vector<Sales_item> vec(in_iter,in_eof);

可以修复第一个bug,至于第二个bug,执行到sort崩溃,不知道如何修复,按说不应该崩溃才是。

some question about unique_copy

看了@pezy 的答案,更加简洁。

unique_copy(ivec.begin(), ivec.end(), back_inserter(ls));

但是我自己也写了一个,运行结果也没问题,但是有点小问题,先贴代码。

    vector<int> ivec{ 0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 6, 7, 8, 9, 9, 5, 4, 4 };
    list<int> ls;
        auto it = ivec.begin();
    sort(ivec.begin(), ivec.end());
    auto f = unique_copy(ivec.begin(), ivec.end(), it);

    for (auto iter = it; iter != f; ++iter)
    {
        ls.push_back(*iter);
    }
    for (auto c : ls)
    {
        cout << c << " ";
    }

本来没什么问题,但是看了pezy的答案后好奇unique_copy到底是怎么工作的,就去搜了一下,找到这个.
根据这个代码,

template <class InputIterator, class OutputIterator>
  OutputIterator unique_copy (InputIterator first, InputIterator last,
                              OutputIterator result)
{
  if (first==last) return result;

  *result = *first;
  while (++first != last) {
    typename iterator_traits<InputIterator>::value_type val = *first;
    if (!(*result == val))   // or: if (!pred(*result,val)) for version (2)
      *(++result)=val;
  }
  return ++result;
}

然后我又大致看了一下vs2013中unique_copy的实现,然后问题来了。
在代码中我们可以看到result是自增的,也就是说函数调用结束之后,result已经不再是原来的迭代器了,从我的这句代码也能看出,auto f = unique_copy(ivec.begin(), ivec.end(), it);,返回的是return ++result;,但是奇怪的是接下来的代码

for (auto iter = it; iter != f; ++iter)
    {
        ls.push_back(*iter);
    }

这段代码我加断点看了一下确实执行了,后面的输出也验证了这一点,但是按道理来说,it已经变了,因为unique_copy中最后会return ++it(中间过程也是有++it的),按说这里的it应该和f是一样的,为啥还会执行for循环里面代码呢?

ex 13.31 为什么按字典升序添加的值使用sort也会调用swap

我自己定义的vector,加了几个元素,结果按顺序添加的元素(如"11","22")也会调用swap输出语句
vectorv1;
v1.emplace_back("11");
v1.emplace_back("22");
sort(v1.begin(),v1.end());

并且输出后发现顺序与添加进去的顺序并没有改变.swap用在哪里了?

关于编译器的一个疑惑

我是用的编译器是vs2013。
今天在做7.32节的时候有一个问题,
关于令成员函数(void clear(ScreenIndex))作为友元,书上说Window_mgr::clear必须在Screen类之前被声明,但是就算把Window_mgr类的定义放在了Screen前面,但是我使用VS2013的时候也没有办法让clear可以访问Screen的private:成员。只有把Window_mgr指定为Screen指定为他的友元的时候才能访问。
不知道是我哪儿写错了还是编译器不支持的问题,我复制了下你的代码,还是这个问题。

追求拷贝语义与移动语义和谐共存的优化之道

C++11 新特性「右值引用」是好东西,真正实现了通过移动语义优化传值的可行性。

最近我在做 @chenshuo 老师的复数类练习,拷贝控制实现如下:

#include <utility>

class Complex {
 public:
  Complex() = default;
  Complex(double real_part, double imaginary_part)
      : real_part_(real_part), imaginary_part_(imaginary_part) {};
  Complex(const Complex &) = default;
  Complex(Complex &&) = default;
  Complex &operator=(Complex right_hand_side) noexcept {
    using std::swap;
    swap(*this, right_hand_side);
    return *this;
  }
  ~Complex() = default;

 private:
  double real_part_ = 0;
  double imaginary_part_ = 0;
};

Complex 类不包含指针,所以很多拷贝控制函数直接显示声明为 default 了。此外,copy and swap 应该是业界公认的赋值运算符最佳实现方式了,不光能自我赋值且做到异常安全性,还都与左值右值和谐相处。

不过接下来我要定义加法运算符,犯难了:在加法多项式(即三项或以上)中,一个加法运算符的运算结果是用不到的临时对象,所以应该用同时支持复制语义和移动语义的友元函数实现加法运算符,毕竟 operator+ 函数有可能会接收一个右值:

// Complex.h
class Complex {

  ...
  double imaginary_part_ = 0;

  friend Complex operator+(
      const Complex &left_hand_side,
      const Complex &right_hand_side);
  friend Complex operator+(
      Complex &&left_hand_side,
      const Complex &right_hand_side);
  friend Complex operator+(
      const Complex &left_hand_side,
      Complex &&right_hand_side);
  friend Complex operator+(
      Complex &&left_hand_side,
      Complex &&right_hand_side);
};

// Complex.cc
Complex operator+(
    const Complex &left_hand_side,
    const Complex &right_hand_side) {
  Complex result(
      left_hand_side.real_part_ + right_hand_side.real_part_,
      left_hand_side.imaginary_part_ + right_hand_side.imaginary_part_);
  return result;
}

然而二元运算符的参数有两个,为了同时支持复制语义与移动语义,我们不得不如此同时重载四个友元函数。别忘了,把以上源代码分割到头文件 complex.hcomplex.cc 文件时,还要在 complex.h 中的 Complex 类作用域外重新声明一遍友元函数。

于是我只好放弃在移动语义上优化二元运算符。改在类内把加法运算符重载为类内成员函数,直接接收一个常量左值引用:

class Complex {

  ...

  const Complex operator+(const Complex &right_hand_side) const {
    Complex sum(
        this->real_part_ + right_hand_side.real_part_,
        this->imaginary_part_ + right_hand_side.imaginary_part_);
    return sum;
  }

}

据我所知,某函数返回值是普通的 Complex 类对象时,那么它一般会返回右值,即用函数体内返回值「复制构造」出的临时对象。于是当 operator+ 接收左值时,直接引用它;当它接收一个被调用且返回普通 Complex 类对象的函数时,后者会先生成临时对象,最后 operator+ 再把这个右值引用成常量左值。

突然,我灵光一闪,直接让 operator+ 函数体内的 sum 变成右值不就好了吗?这样在多项式运算中,不会再对函数体内返回值「复制构造」出临时对象,而是直接把它移动到临时对象上,毕竟 Complex 已经定义了移动构造函数。于是如今 operator+ 优化如下:

class Complex {

  ...

  const Complex operator+(const Complex &right_hand_side) const {
    Complex sum(
        this->real_part_ + right_hand_side.real_part_,
        this->imaginary_part_ + right_hand_side.imaginary_part_);
    return std::move(sum);
  }

}

于是在如此干净简洁、无冗余多次重载的实现下,一个小小的「把函数体内返回值移动到临时对象上」开销就无关紧要了。同理,应该可以对「在函数体内定义局部对象并返回其非引用值」的其它函数如法炮制。

好了,以上是我的随笔,欢迎大家各抒已见。有错误一定要当场斧正!

6.48对assert的使用为什么不对?

当因为输入无效而终止循环那么assert(cin)将报错,否则输入就是sought,这种情况assert(cin)将跳过,这和assert(s==sought)的效果是一样吧?
assert(cin)怎么可能一直为true呢?不明白这句话的意思

问个初级的问题:下面的例子里传值参数与传引用参数的区别?

  #include <iostream> 
  using namespace std;
  void a(int);
  void b(int&);

  int main()
  {
  int s = 0, t = 10;
  a(s);
  cout << s << endl;
  b(t);
  cout << t << endl;
  return 0;
  }
 void a(int i)
 {
 ++i;
 cout << i << endl;
 }
void b(int& j)
{
++j;
cout << j << endl;
}

运行结果是:
1
0
11
11
我以为的结果是
1
0
11
0
谁能解释运行结果的意思? 不是很懂啊

Telegram 群:C++ 众

http://tech.acgtyrant.com/C-%E4%BC%97/

如果您用 Telegram 且有兴趣加入并一起讨论,留言申请即可。

审核标准是「教养」,比如对事不对人,不轻易评论甚至攻击不熟悉的事物,少谈主义多研究问题等。

该 issue 一周后我会自行关掉。

Ex12.11解释问题

从程序的运行上来看,运行后,的确会有double free or corruption的错误。

As a result, at end of this main function p will free the memory that has been freed inside process (). That's why "double freed or corruption" was generated.

从这个解释上来看,是 main 函数退出时,p 原来指向的内存被再次释放导致的。
但是,如果测试程序如果在 process(std::shared_ptr<int>(p.get()));
后加上一句比如 cout<<"exit main"<<endl;
会发现并没有输出 exit main 这句话就已经报错 double free or corruption。
同样,如果 gdb 一下,这个错误也是 process 一返回就报错的。

shared_ptr<int> p(new int(42));share_ptr<int>(p.get()) 是两个独立的 shared_ptr 指向相同的内存,process 退出时会销毁函数的局部变量,指向的内存 int(42) 同样被释放,感觉没有double free啊
不知道问题出在了哪里??

15.7.4继承的构造函数

class Bluk_quote:public Disc_quote{
    public:
        Bluk_quote()=default;
        Bluk_quote(const string& book,double price,size_t qty,double  disc):Disc_quote(book,price,qty,disc){}
        double net_price(size_t) const override;
};



class Bluk_quote:public Disc_quote{
    public:
        using Disc_quote::Disc_quote;   //继承Disc_quote的构造函数
        double net_price(size_t) const override;
};

俩个构造函数有啥区别吗
做到15.29必须用第二个构造函数运行结果才能正确

指向常量的常量指针 是否与 指向常量的引用 类似

const int ival = 1024; 
const int *const pi = &ival; 

指向常量的常量指针=指针中存放地址的值和所指对象,都不能改变。
即 pi 一直指向 ival,同时ival 对象的值是不能被改变的。

const int ival = 1024; 
const int &ri = ival; 

指向常量的引用,所指向的对象不能改变,因为引用是别名所以引用是一直指向原对象。
即 pi 一直指向 ival,同时ival 对象的值是不能被改变的。

Q: 两者在某时是一样的?

As a beginner , the problem might be foolish!
有问题不知道答案,总是感觉有些不舒服。

谢谢 解答

A question about ex11_8.cpp

The time it takes to insert an item into a vector is proportional to the number of items already in the vector. The time it takes to insert an item into a set is proportional to the log of the number of items. If the number of items is large, that's a huge difference. Log(100,000) is 5; that's a major speed improvement. The same goes for removal.

答案的意思应该说vector插入元素耗费时间跟元素个数成比例增长,与set元素个数成对数比例增长。如果元素个数足够多,应该是set耗费时间相对较少。中间那句Log(100,000) is 5; that's a major speed improvement.是什么意思?

2.本题答案给的代码不够完善,题目说

Write a program that stores the excluded words in a vector instead of in a set.

但是给的代码中并没有store,所以应该完善一下,@pezy

vs2012 x86 本机工具命令提示 cl xx.cpp , 显示“无法打开文件“LIBCMT.lib””...

由于一直没用过 Git(分布式版本控制),这两天学习了下并在本地配置好,也把 Cpp-Primer clone 到了本地仓库。
看到的一个文件夹中有 N 多 cpp,而且每个都有 main 函数,应该不是在 vs2013 中 1 个 cpp 建 1 个解决方案那么繁琐,google 了下,可以直接用 vs2012 x86 本机工具命令提示.exe 来调试,出现了 cl 不是内部命令,加下环境变量解决问题了,后来又出现了 无法打开文件“LIBCMT.lib” 的问题,目前还没解决,求肋下。

sizeof(arr) 时的一些问题

    unsigned long long ival1 = 1024;
    unsigned long ival2 = 1024;
    unsigned int ival3 = 1024;
    unsigned short ival4 = 1024;
    cout << ival1 << " | " << sizeof(ival1) << endl; // char 8位,sizeof char类型为1, long long 64位,所以此行为 8
    cout << ival2 << " | " << sizeof(ival2) << endl; // long 32位,同理行为 4
    cout << ival3 << " | " << sizeof(ival3) << endl; // 一般定义 int 会自动提升为 long 的精度,所以也为 4,是这样?
    cout << ival4 << " | " << sizeof(ival4) << endl; // short 为16位,此行为 2    , 无符号 8位, Math.pow(2,8)=256, 1024 会溢出,所以自动提升了精度?

    int arri[10], *p = arri;
    cout << sizeof(arri) / sizeof(*arri) << endl;   // *arri 为指向数组 arri 第一个元素的指针,sizeof(arri) 为40, sizeof(*arri) 为4
    cout << sizeof(p) / sizeof(*p) << endl;

话说,最后两个的一开始的答案是:11/10
cout << sizeof(arri) / sizeof(*arri) << endl;我后面的注释如果对,就应该了解了
最后一个,还是不怎么理解
p*p 的理解,如下:

    int ival = 1024, *p = &ival;    //  p 是指向整型变量 ival 的指针
    *p = 0;                         //  对 p 进行解引用,其实得到的是指针 p 所指向的对象 ival, 所以相当于 ival = 0; 这条赋值语句
    p = 0;                          // 没有解引用时就是自己,所以 p 指针就变成了空指针,不指向任何对象

Q:cout << sizeof(p) / sizeof(*p) << endl; 来帮我解释下,谢谢

Exercise 2.3.2[by Xiao`]

Xiao` :

2.23:给定指针p,你能知道它是否指向了一个合法的对象吗?如果能,叙述判断的思路;如果不能,请说明原因.

指针有4种,如下:

  1. 指向一个对象int i=1024; int *pi=&i;
  2. 指向紧邻对象所占空间的下一个位置(话说才看到第2章,此处不懂);
  3. 空指针int *p1=nullptr,*p2=0,*p3=NULL;.
  4. 无效指针,上述情况之外的其他值.
    1.2是合法的对象,3.4应该是不合法的. 是这样么?

再者,这题目怎么解?

定义在函数体/类的内置类型有「默认初始化(default initialized)」吗?

中译版第 40 页则指出:

定义在函数体内部的内置类型变量将不被初始化(uninitialized)

问题有两个:

  1. 当定义在类(class/struct)内部的数据成员为内置类型时,它也不被初始化吗?
  2. 我们可以说这个内置类型在默认初始化中不被初始化,还是只能说它不被默认初始化呢?即前者相当于名词「阶段」,后者则如同动词「初始化」,我不知道 C++ 所谓的「默认初始化」到底该理解成哪一种语义。

原版第 44 页开头即是相关文。

关于typedef的问题

刚刚写代码遇到一个奇怪的问题,环境:win7 + code::block ,代码如下:

struct m_num
{
    int num;
    bool flag = true;
};
int main()
{
    int N = 0, K = 0;
    cin >> N >> K;
    typedef m_num arrT[K];
    arrT data[N];
    return 0;
}

这样的代码没有报错,为什么呢?数组的大小不是要预编译的时候就要确定好吗?
而且如果我把那几行代码放入全局中,就会报错,

struct m_num
{
    int num;
    bool flag = true;
};
int N = 0, K = 0;
cin >> N >> K;
typedef m_num arrT[K];
arrT data[N];
int main()
{
    return 0;
}

报错内容:
error: array bound is not an integer constant before ']' token
error: 'arrT' does not name a type

这是为什么呢?@pezy @Mooophy

类内初始值和构造函数的初始值

class Test
{
    public:
    Test()=default;
    Test(int i,string j):a(i),b(j);
    private:
    int a=0;
    string b;
}

现在我调用第二个构造函数实现一个Test类的对象t,如下:

Test t(6,"aaa");

那么,现在有一个问题。
在书上的7.4.1节名字查找提到了类内部的解析方法:先编译所有成员的声明,然后是函数体。
在7.5节构造函数再探一节中讲到了构造函数初始值是对成员直接初始化。。。
在这个例子中:成员a与成员b分别被构造函数初始化成6与aaa。为什么不是在编译阶段a与b分别初始化成了0与空串,然后再被分别赋值了?

Exercise 8.12的答案

C++ primer 5th Page 322.Exercise 8.12

Why didn’t we use in-class initializers in PersonInfo?

答案是

Cause we need a aggregate class here. so it should have no in-class initializers.

这里为什么需要aggregate class?
我觉得原因应该是没有必要这么做吧。

g++ 用-std=c++11编译不过insert的返回值新特性

这是代码,目的是测试新标准insert接受元素范围的版本。vs2013可以正常运行
vector v;
list lst{1,2};
auto it = v.insert(v.end(),lst.begin(),lst.end());
g++报的错
error: 'void it' has incomplete type
返回值类型为void

some question about ex10.30

我看@pezy 的答案用了这种写法,

 std::copy(vec.cbegin(), vec.cend(), std::ostream_iterator<int>(std::cout, " "));

然后我又尝试了这种写法,

    vector<int> ivec(istream_iterator<int> (cin), istream_iterator<int> (eof));

此种方法在vs2013中并没有报错,但是当我加上sort(ivec.begin(), ivec.end());时,就会报错,看报错的原因应该是ivec的原因,但是不知道为什么?

书上这一节有个从迭代器范围构造vec的写法,不过书上是这么写的:

        // 这种方法没问题
    istream_iterator<int> in_iter(cin), eof;
    vector<int> ivec(in_iter,eof);

const和返回*this的问题

7.1.2节谈到了引入const成员函数的作用,7.3.2节又提到了从const成员函数返回*this,有点混淆了,下面举个例子(在类中与本问题无关的部分都被省略)

class Screen
{
public:
    Screen set2() const
    {
        return *this;
    }

    Screen& set5()const
    {
        return *this;
    }
};

很显然,有些是错误的。
this类型默认情况下是指向类类型的非常量版本的常量指针

问题在这里:

头文件中的set5()已经报错。
我的理解:因为是this类型是const Screen *const,但是返回值类型只是Screen类型的引用(非常量类型),所以报错???
但是,为什么在set2() 中就没有报这个错呢??两个成员函数的区别只是返回值一个是引用但是一个不是?

C++ primer里那个书店程序

#include <iostream>
#include "Sales_item.h"

int main()
{
    Sales_item total; // variable to hold data for the next transaction

    // read the first transaction and ensure that there are data to process
    if (std::cin >> total) {
        Sales_item trans; // variable to hold the running sum
        // read and process the remaining transactions
        while (std::cin >> trans) {
            // if we're still processing the same book
            if (total.isbn() == trans.isbn())
                total += trans; // update the running total 
            else {
                // print results for the previous book 
                std::cout << total << std::endl;
                total = trans;  // total now refers to the next book
            }
        }
        std::cout << total << std::endl; // print the last transaction
    }
    else {
        // no input! warn the user
        std::cerr << "No data?!" << std::endl;
        return -1;  // indicate failure
    }

    return 0;
}

这是答案,然后我运行时输入a 1 2 b 1 2结果只会显示出a商品的情况,b无法显示。我试了ctrl+z也是不行。现在不知道要怎么搞才能让ab商品一起输出,希望大神能帮忙解决下这个疑惑。

ex12_24中ignore函数的作用

代码如下:

#include <iostream>

int main()
{
    // need to tell the size.
    std::cout << "How long do you want the string? ";
    int size{0};
    std::cin >> size;
    char *input = new char[size+1]();
    std::cin.ignore(); //*********************************************//
    std::cout << "input the string: ";
    std::cin.get(input, size+1);
    std::cout << input;
    delete [] input;
    // Test: if longer than the array size, we will lost the characters which are out of range.
}

输入测试数据 5[Enter]sssss 测试无误,但是删去cin.ignore()后,测试发现输入5之后就不再接受输入。

ignore()默认的参数是1,EOF表示清空缓冲区中的一个字符。但是在输入5之后敲击回车原则上是无影响的,因为cin>>size,中的cin>>该操作符是根据后面变量的类型读取数据。输入结束条件 :遇到Enter、Space、Tab键。*对结束符的处理 *:丢弃缓冲区中使得输入结束的结束符(Enter、Space、Tab) 。

删去cin.ignore()的条件下:
此处输入5后,缓冲区内无残留数据,因此我认为不加cin.ignore()也是可以的,但是实践表明不行,不知道是为什么?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.