我正在玩模板。 我有以下模板来对矢量的元素求和:
#include<vector>
#include <iostream>
template <class summable>
summable sum (const std::vector<summable> data, summable initial_value = 0){
std::cout<<"in the function"<<std::endl;
for (auto i : data){
initial_value += i;
}
return initial_value;
}
它对数字类型工作得非常好。但是如果我尝试传递一个字符串向量,我不会得到任何编译错误但是函数没有被调用。
这是我的函数main
:
int main(int argc, char** argv) {
vector<string> s {"Hello" , " ", "There" };
cout<<"Before calling the function\n";
cout<<sum(s);
return 0;
}
我得到了
在调用函数之前
作为输出。
如果我将函数调用更改为cout<<sum(s, string(" "));
,则函数按预期工作。我猜这与我定义默认参数的方式有关,因为0
不是字符串的有效值(我认为)。
我的问题是为什么我没有收到任何错误?因为它能够编译它应该运行,不是吗?
答案 0 :(得分:5)
你走在正确的轨道上。对于std::string
,值0
与nullptr
相同,并匹配使用const char*
的构造函数。
但是,将空指针传递给该构造函数是未定义的行为。未定义的行为意味着任何都可能发生。
标准说:
basic_string(const charT* s, const Allocator& a = Allocator());
要求:
s
指向traits::length(s) + 1
个至少charT
个元素的数组。效果:构造类
basic_string
的对象并从中确定其初始字符串值 长度为charT
的{{1}}数组,其第一个元素由traits::length(s)
指定,如下所示 表67。
因此,如果s
为空(或s
),则它不会指向0
的数组,并且违反了先决条件。
顺便说一下,您可以使用charT
作为参数的默认值。这适用于任何默认的可构造类型。