为什么通过带有文字编号的引用调用会出现"无匹配函数"错误?
Why a "no matching function" error for call by reference with literal number?
问题要求创建一个程序,要求用户输入一些文本,并且该文本将被星号包围,具体取决于屏幕的宽度,例如,如果用户输入"Hello world",则输出应为:
****************
* Hello World! *
****************
我尝试创建函数,但由于显示的最小代码的编译器错误而卡住了。
问:为什么它告诉我no matching function
within_width(text, 80)
?
我拥有的一些代码如下:
#include <iostream>
#include <string>
void display_header (std::string &header) {
std::string text;
header = text;
}
bool within_width (std::string& text, unsigned short int& max_width) {
}
int main() {
std::string text;
std::cout << "Please enter header text: ";
std::getline(std::cin, text);
if (within_width(text, 80)) {
// call the display_header function and pass in the text
// inputted by the user
} else {
std::cout << text;
}
return 0;
}
函数的声明
bool within_width (std::string& text, unsigned short int& max_width)
要求一个无符号的短 int变量,因为它有一个引用参数,请参阅第二个&。
为了满足它,您需要将值 80 放入一个变量中,并将该变量作为参数。
unsigned short int MyWidth=80;
if (within_width(text, MyWidth))
或者(但我假设您不被允许(您可以使用按值参数调用
bool within_width (std::string& text, unsigned short int max_width)
然后你可以如图所示打电话。
我不会在这里给出完整的答案,只是一些线索。
display_header()
函数和within_width()
函数需要知道参数中给出的字符串,但不能修改它;因此这个参数的类型应该是const std::string &
(缺少const
(。within_width()
函数的第二个参数只是一个整数,它将与字符串的长度进行比较;你不需要通过引用(或至少const
(传递它,而是通过值传递它。在这里,(非const
(引用阻止传递文字常量80
。
(这似乎是版后问题的主要关注点(- 你需要一步一步地推理。
- 所有这些都取决于字符串的大小(12表示
Hello World!
(;这些信息可以通过size(text)
(或text.size()
((https://en.cppreference.com/w/cpp/iterator/size(
(https://en.cppreference.com/w/cpp/string/basic_string/size(获得。 - 这个大小必须与
max_width
进行比较 - 显示带有
header
的行将需要另外 4 个字符,因为*
将附加前缀并附加*
字符。 - 因此,周围的两条线也将具有长度
size(header)+4
。 - 为了创建这样一个由
*
组成的字符串,你可以使用一个构造函数std::string
取两个参数:字符数和要重复的字符。
(https://en.cppreference.com/w/cpp/string/basic_string/basic_string(
以 - 正确的顺序将所有这些发送给
std::cout
。
- 所有这些都取决于字符串的大小(12表示
编辑: 只是注意到这个答案可能远远超出了你被赋予的任务范围(只是填写了你老师提供的一些骨架(。
我仍然会把它留在这里,以说明 任意输入可以做什么。也许你想比你被问到的更进一步的实验......
bool within_width(...)
很简单:string.length() <= max
– 稍等片刻,您需要在输出的开头和结尾考虑星号和空格,因此:max - 4
但是你可以做得更好,你可以拆分字符串,最好在单词边界。不过,这有点困难,更困难:
std::vector<std::string> lines;
// we'll be starting with an initially empty line:
auto lineBegin = text.begin();
auto lineEnd = text.begin();
for(auto i = text.begin(); i != text.end(); ++)
// stop condition empty: we'll stop from inside the loop...
{
// ok, we need to find next whitespace...
// we might try using text.find_first_of("..."), but then we
// need to know any whitespace characters ourselves, so I personally
// would rather iterate manually and use isspace function to determine;
// advantage: we can do other checks at the same time, too
auto distance = std::distance(lineBegin, i);
if(std::distance(lineBegin, i) > maxLineLength)
{
if(lineEnd == lineBegin)
{
// OK, now we have a problem: the word itself is too long
// decide yourself, do you want to cut the word somewhere in the
// middle (you even might implement syllable division...)
// or just refuse to print (i. e. throw an exception you catch
// elsewhere) - decide yourself...
}
else
{
lines.emplace_back(lineBegin, lineEnd);
lineBegin = lineEnd; // start next line...
}
}
// OK, now handle current character appropriately
// note: no else: we need to handle the character in ANY case,
// if we terminated the previous line or not
if(std::isspace(static_cast<unsigned char>(*i)))
{
lineEnd = i;
}
// otherwise, we're inside a word and just go on
}
// last line hasn't been added!
lines.emplace_back(lineBegin, lineEnd);
现在,您可以计算包含的所有字符串的最大长度。最好:在向向量添加新行时正确执行此操作,这样就不需要单独的循环了......
您可能已经注意到,我没有删除字符串末尾的空格,因此您无需添加自己的空格,可能与最后一个字符串分开(因此您可以添加lines.back() += ' ';
(。
到目前为止,丑陋的部分是我留下了多个后续空格。最好是在分成几行之前删除,但请注意,您需要至少留下一行。所以:
auto end = text.begin();
bool isInWord = false; // will remove leading whitespace, if there is
for(auto c : text)
{
if(std::isspace(static_cast<unsigned char>(c)))
{
if(isInWord)
{
*end++ = ' '; // add a single space
isInWord = false;
}
}
else
{
*end++ = c;
isInWord = true;
}
}
这会将所有单词移到字符串的开头,但我们尚未删除字符串的剩余部分:
text.erase(end, text.end());
很好,其余的很简单:
- 迭代最大长度,在每个循环中打印一个星号
- 遍历向量中的所有字符串:
std::cout << "* " << line << "*n";
- 重复初始循环以打印星号的第二行
最后:您引入了 80 个字符的固定行限制。如果控制台更大,您就不会使用整个可用宽度,这可能是可以接受的,如果它更小,您将在错误的位置折断线。
您现在可以(但这是可选的(尝试检测控制台的宽度 - 之前已经问过,所以我不会更深入地介绍。
最后说明:上面介绍的代码未经测试,所以不能保证没有错误!
- Rcpp并行无匹配函数,用于调用"转换"
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- 如何摆脱C++中的枚举不匹配错误?
- 运算符重载错误无匹配运算符<<
- 为什么通过带有文字编号的引用调用会出现"无匹配函数"错误?
- C++:提升 ptree 删除子项:无匹配功能
- 无匹配函数呼叫getline()
- 自定义删除器,用于shared_ptr<>给出"无上下文错误"
- 错误:呼叫构造器的匹配函数无匹配功能
- C 汇编错误:无匹配的构造函数以进行初始化
- 错误代码:无匹配函数供呼叫
- 错误:如果(object1 == object2),“操作器==”无匹配(操作数类型为“ const class”和“
- 为链接列表构建迭代器类(错误:无匹配的构造函数以初始化)
- 错误:“操作员^”无匹配
- std::查找"错误无匹配函数"
- C 错误无匹配函数
- C 模板错误无匹配操作员过载
- 操作员无匹配==错误,C
- C :Tusing Boost Unordered_map错误:无匹配函数调用
- C 无匹配函数用于呼叫错误(默认为参考通过)