initializer_list对于未知数量的参数,实际的好处和目的是什么?为什么不直接使用vector并完成它?
事实上,它听起来只是vector另一个名字.何必?
我看到的唯一"好处" initializer_list是它有const元素,但这似乎不足以发明这种全新的类型.(const vector毕竟你可以使用.)
那么,我在做什么?
我们都是便携式C/C++程序的粉丝.
我们知道sizeof(char)或sizeof(unsigned char)总是1"字节".但是1"字节"并不意味着具有8位的字节.它只是一个"机器字节",其中的位数可能因机器而异.看到这个问题.
假设您将ASCII字母"A"写入文件中foo.txt.这些天,在任何普通机器上都有一个8位机器字节,这些位将被写出来:
01000001
Run Code Online (Sandbox Code Playgroud)
但是如果要在具有9位机器字节的机器上运行相同的代码,我想这些位将被写出来:
001000001
Run Code Online (Sandbox Code Playgroud)
更重要的是,后一台机器可以将这9位写为一个机器字节:
100000000
Run Code Online (Sandbox Code Playgroud)
但是如果我们要在前一台机器上读取这些数据,我们就无法正常工作,因为没有足够的空间.不知何故,我们必须首先读取一个机器字节(8位),然后以某种方式将最后的1位变换为8位(机器字节).
程序员如何正确地协调这些事情?
我问的原因是我有一个编写和读取文件的程序,我想确保它不会在5年,10年,50年后中断.
为什么C++标准会打扰发明std::exception类?他们的好处是什么?我的理由是:
try
{
throw std::string("boom");
}
catch (std::string str)
{
std::cout << str << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
工作良好.后来,如果我需要,我可以制作自己的轻量级"异常"类型.那我为什么要打扰std::exception?
我的代码中出现了链接器错误.我已经确定了下面的基本要点.
此代码为链接器提供错误"vtable for Foo",引自:Foo :: Foo()
class Foo {
public:
Foo();
virtual ~Foo() = default;
};
Foo::Foo() { }
Run Code Online (Sandbox Code Playgroud)
但是这段代码没有给出任何错误:
class Foo {
public:
Foo();
virtual ~Foo() { }
};
Foo::Foo() { }
Run Code Online (Sandbox Code Playgroud)
为什么?我认为这= default应该与那些空方括号基本上做同样的事情.
更新:我使用的是"Apple LLVM编译器4.1",它是Xcode 4.5.2的一部分.它可能是这个编译器中的错误吗?它可能适用于最新的GCC(Apple不再发售).有关编译器的讨论,请参阅下面的注释.
更新2:如下所述,更改行以virtual inline ~Foo() = default;消除此错误.这难道不是仅仅有是一个错误?看起来编译器在没有明确写出的情况下不识别内联函数inline.
我有一个cheesesales.txtCSV文件,包含我最近的所有奶酪销售.我想创建一个CheeseSales可以执行以下操作的类:
CheeseSales sales("cheesesales.txt"); //has no default constructor
cout << sales.totalSales() << endl;
sales.outputPieChart("piechart.pdf");
Run Code Online (Sandbox Code Playgroud)
上面的代码假定不会发生任何故障.实际上,失败将会发生.在这种情况下,可能会发生两种故障:
我的问题很简单:您如何设计此代码来处理故障?
一个想法:bool从常规方法返回a 表示失败.不知道如何处理构造函数.
经验丰富的C++程序员如何做这些事情?
另一个问题的答案
解释了为什么我们(据说)不能拥有const对象的容器.例如,这是不允许的:
vector<const int> v; //not allowed
Run Code Online (Sandbox Code Playgroud)
但为什么pair允许第一个对象const呢?实际上,这是对象pair内部的s 所发生的事情map.我错过了什么吗?
将非常感谢对这种现象的详细和直观的解释.
目前,我有一个这样的函数模板,它将a转换vector为a string(只是一个自然的字符串,用逗号分隔元素):
//the type T must be passable into std::to_string
template<typename T>
std::string vec_to_str(const std::vector<T> &vec);
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,这只是针对其元素可以传递到内置的载体std::to_string功能(如int,double等)
用允许的评论记录是否被认为是一种好的做法T?如果没有,我该怎么办?是否有可能以更好的方式执行此操作?
你能说出一些从C++中获取当前"yyyymmdd"(例如"20121219")字符串的简单方法吗?允许Boost,因此应该更容易.我可以使用,ctime但设置该结构有点痛苦.
我已经这样做了
boost::gregorian::date current_date(boost::gregorian::day_clock::local_day());
int year_int = current_date.year();
int month_int = current_date.month();
int day_int = current_date.day();
Run Code Online (Sandbox Code Playgroud)
然后使用ints将strings 转换为s
std::string year = boost::lexical_cast<std::string>(year_int);
std::string month = boost::lexical_cast<std::string>(month_int);
std::string day = boost::lexical_cast<std::string>(day_int);
Run Code Online (Sandbox Code Playgroud)
但问题是第1天应该是"1"而不是"01".
我正在读C++ Primer,第5版,其中p.71他们首先给出这个代码示例:
const int ci = 0, &cj = ci;
decltype(ci) x = 0;
decltype(cj) y = x;
decltype(cj) z; //error
Run Code Online (Sandbox Code Playgroud)
然后他们说:
值得注意的
decltype是,唯一的上下文是定义为引用的变量不被视为它引用的对象的同义词.
这是什么意思?我不明白.在y有指x.那捕获的是什么?
我们有一个Base类和一个Derived派生自的类Base.
在其他一些类中,我们希望拥有一个类型的成员shared_ptr<Base>.
我们不能Base直接使用该类型,因为像这样的直接复制将排除子类.
但是,我们仍然希望Base在构造时"复制" (或子类)对象,因为我们想要排除它被修改的可能性.
处理此问题的经典方法是将虚拟成员函数clone()放入Base类中,Base然后可以实现每个子类.clone()然后每个人都会返回自己的"副本" - 例如,Derived会返回make_shared<Derived>(*this).
这种方法的问题是,这需要每个新的子类Base来实现这个clone()功能.每个代码clone()都是样板文件,一直重复它似乎有点不自然.
自C++ 11以来有没有更好的方法呢?
可能重复:
c ++ 11中的自动引用
我学习C++越多,我越了解到目前为止(差不多;见下文)其中的一切基本上都是有道理的.我发现我并不是真的需要学习任何规则,因为一切都像预期的那样.因此,最重要的是要真正理解这些概念,然后其余的事情就会照顾好自己.
例如:
const int ci = 0;
auto &a = ci; //automatically made const (const int &)
Run Code Online (Sandbox Code Playgroud)
这有效并且有意义.任何其他类型的东西a都是荒谬的.
但现在就拿这些:
auto &b = 42; //error -- does not automatically become const (const int)
const auto &c = 42; //fine, but we have to manually type const
Run Code Online (Sandbox Code Playgroud)
为什么第一个错误?为什么编译器不会自动检测到这个?为什么const必须手动输入?我想要从根本上理解为什么事情有意义,而不必刻意学习任何严格的规则(见上文).
首先让我问一个普遍的问题:
然后是一个特定的:
const?换句话说,如果您尝试创建const它的非对象,则会遇到编译时错误的类.在许多情况下,这似乎是很自然的事情,但C++不允许这样做.这背后的原因是什么?(当然,我可以让所有的成员const,但这有点像一个copout.)我Cheese上课了.在我的程序中,我经常收集奶酪,主要是vector<Cheese>对象.
我希望能够eat()收集奶酪,如下所示:
vector<Cheese> cheeses;
//cheeses = ...
cheeses.eat();
Run Code Online (Sandbox Code Playgroud)
这该怎么做?如何在vector<Cheese>课程中添加新的成员函数?我应该只是对vector<Cheese>类进行子类化,命名子类CheeseCollection并在那里添加成员函数,还是有更好的方法?
来自Objective-C,我习惯了类,它允许我向类添加函数("方法").有类似的东西在C++中可用,还是在C++中像疯了似的子类被认为更自然?