为什么隐式转换在累积中不起作用?
Why does implicit conversion not work in accumulate?
这是C++程序:
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int test_string(const string & str) {
return str.size();
}
void main() {
test_string(""); //can compile
vector<string> v;
string sum = accumulate(v.cbegin(), v.cend(), ""); //cannot compile
}
我想在通用 STL 函数accumulate
的调用中使用从const char *
到string
的隐式转换。我知道从const char *
到字符串的转换不是显式的,因此我们可以将const char *
参数传递给需要string
类型的调用。这可以通过上述test_string
函数来证明。但是当我在accumulate
中做同样的事情时,编译器抱怨:
error C2440: '=': cannot convert from 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' to 'const char *'
仅当我将""
替换为string("")
时,代码才有效。我不明白为什么隐式转换适用于我的自定义函数,但在accumulate
中不起作用。你能解释一下吗?多谢。
PS:我正在使用Visual Studio 2015。
std::accumulate 声明为
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
这意味着模板参数T
是从传入的参数中推导出来的(即""
)。然后它会const char*
.另一方面,编译器如何执行隐式转换?哪种类型应该是目标类型?
您可以显式传递std::string
,也可以显式指定模板参数。
// pass a std::string exactly
string sum = accumulate(v.cbegin(), v.cend(), string(""));
// T is specified as std::string explicitly
// "" will be implicitly converted to std::string
string sum = accumulate<decltype(v.cbegin()), string>(v.cbegin(), v.cend(), "");
看看 cpp偏好的可能实现
template<class InputIt, class T>
T accumulate(InputIt first, InputIt last, T init)
{
for (; first != last; ++first) {
init = init + *first;
}
return init;
}
当您以 DO 方式调用函数时,InputIt
将被推导为vector<string>::const_iterator
,T
将被推导为const char*
。 正如你在 for 循环中看到的,执行"累积"的代码行是这样的
init = init + *first
在作业的右侧,*first
将评估为string&
,init
将评估为const char*
。 然后,您将使用连接const char*
和std::string
实例的std::string::operator+
来获取std::string
。 然后,您正在尝试将std::string
分配给const char*
变量。 这是不合法的。
这不起作用,因为std::string
对象不是隐式可转换或可分配给const char*
的,但情况正好相反。
要解决此问题,请将您的代码更改为以下内容(请注意,我在字符串文字后加上了s
,这是用户定义文字(在本例中计算为std::string
)的 C++14 语法 http://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
int main() {
using namespace std::string_literals;
vector<string> v;
string sum = accumulate(v.cbegin(), v.cend(), ""s);
}
另如评论中所述,void main()
更改为int main()
。 有关更多信息,请参阅 main() 在 C 和 C++ 中应该返回什么?
我不明白为什么隐式转换适用于我的自定义函数,但在累积中不起作用。你能解释一下吗?
甚至没有尝试隐式转换,std::accumulate 只是尝试通过将std::string
实例添加到初始化为auto sum = "";
的总和来累积,并且您会收到与在这种情况下相同的错误:
std::string s = "abc";
const char* sum = "";
sum = sum + abc; // <-- error
仅当我用字符串(")替换"时,代码才有效
因为这种方式内部累加器的类型是std::string
的,一切都按预期工作。你也可以这样做:
string sum = accumulate(v.cbegin(), v.cend(), ""s);
作为旁注,它应该是int main() { ... }
,而不是void main
- 嘿,我正在尝试将此c ++转换为javascript,但有些东西不起作用
- C++实用程序::转换在静态链接库中不起作用
- 将 cmake 代码段转换为函数 - 不起作用
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 我的代码在作为参数传入 .begin() 时不起作用,但在我将 .begin() 转换为迭代器后工作
- 从 C++ 转换的 C# 代码不起作用
- 句子转换器在存在新行的情况下不起作用
- 为什么隐式转换在累积中不起作用?
- 将向量的大小()转换为 int 不起作用
- 为什么转换不起作用
- 隐式用户定义的转换不起作用,因为在编译C 时无法识别运算符和转换构造函数
- 在C 中使用Atof将字符串转换为小数不起作用
- C++ 将 int 转换为双精度不起作用
- 从中间器转换字符串不起作用,出了什么问题?
- pybind11:Python 到 C++ 数据类型转换不起作用
- 将std ::复制转换为std :: memcpy不起作用
- 为什么返回Sfinae转换操作员不起作用
- 将char转换为std::string不起作用
- 尝试将工作python程序转换为C++但不起作用
- sqlite3_exec()!= SQLITE3_OK. 尝试在 OOP 中转换不起作用