变量初始化无法使用逗号运算符进行编译
Variable initialization fails to compile with comma-operator
为什么以下代码中指示的行(在main()中)无法编译?
#include <iostream>
#include <string>
#include <map>
template< typename _T > struct Inventory : public std::map< _T, int >
{
bool getat(int i, _T &t, int &n)
{
if ((i < 0) || (i >= (int)this->size())) return false;
int c=0;
typename std::map< _T, int >::iterator it = this->begin();
while ((c < i) && (it != this->end())) { c++; it++; }
t = (*it).first;
n = (*it).second;
return true;
}
Inventory &operator=(_T t) { (*this)[t]++; return *this; }
Inventory &operator,(_T t) { return operator=(t); }
};
int main()
{
int i=0, quantity;
std::string item;
//***Fails to compile:***
//Inventory< std::string > inv = "a","b","c","a","c","d","e";
Inventory< std::string > inv;
inv = "a","b","c","a","c","d","e"; //but this is fine
inv = "e","f";
while (i < (int)inv.size())
{
if (inv.getat(i, item, quantity))
std::cout << i << ": " << item << " -> " << quantity << "n";
i++;
}
return 0;
}
这称为复制初始化。简而言之,它使用转换构造函数,然后使用复制构造函数来构造inv
,而不是像您期望的那样operator =
。
Inventory< std::string > inv = "a","b","c","a","c","d","e";
是无效的语法。像Inventory< std::string > inv = "a"
这样的东西会首先尝试从"a","b","c","a","c","d","e"
创建一个临时Inventory
,然后将该临时用作复制构造函数的参数来构造inv
。 在这种情况下,永远不会调用operator =
。
您的第二个版本之所以有效,是因为
Inventory< std::string > inv;
调用默认构造函数,并且
inv = "a","b","c","a","c","d","e";
对已初始化的对象调用operator =
。
你的问题是,在一种情况下,逗号是标点符号(和运算符重载不适用),在另一个中,它是一个算子。 不起作用的定义基本上是等效的之:
Inventory<std::string> inv = "a";
Inventory<std::string> "b";
Inventory<std::string> "c";
// ...
正因为如此,重载operator,
总是糟糕的设计;当逗号是一个运算符,当它不是时,就太微妙了。
执行此类操作的常用方法是创建一个相关类收集参数,并将其传递给构造函数:
Inventory<std::string> inv = Collector().add("a").add("b")...;
您还可以重载运算符并使用它,而不是函数 add
. 但我没有看到一个可能的运算符(<<
,灵感来自ostream
?或者你可以重载构造函数和operator()
Collector
,并写:
Inventory<std::string> inv = Collector("a")("b")...;
然后,您将使用相同的语法进行赋值。 (你真的没有想要一些适合作业的东西,而不是复制的东西建设。
相关文章:
- C++中的条件运算符 ( ? : ) 可以编译时吗?
- 编译"运算符删除"时C++编译器如何工作?
- 为什么 std::make_shared 无法编译带有已删除运算符 new 的类型?
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- 编译我的 3 个文件时,我收到错误,说"运算符="不匹配
- 使用堆栈编译错误的 C++ 反向行没有运算符匹配操作数
- 代码块编译错误与运算符<<不匹配
- ostream 运算符的编译时重载
- 编译Qt项目给出了对运算符delete(void*,unsigned int)的未定义引用
- <<运算符覆盖使用 g++ 而不是窗口编译
- 为什么有条件编译运算符模板会更改另一个运算符的可用性?
- 在 sizeof 运算符上强制编译时错误
- 如何在C++编译时检查运算符的特定重载是否存在
- 为模板类编写二进制加法运算符. 编译错误
- 重载运算符编译错误?
- 三元运算符编译
- C++模板运算符编译错误
- C++中重载运算符编译但崩溃
- C++ GMP 库 ostream 运算符<<编译但不链接?
- 重载运算符+编译错误没有匹配函数调用...