2016-02-21 37 views
2

我正在玩模板。 我有以下模板来总结一个向量的元素:数字类型和字符串的模板函数总和

#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

你初始化字符串0 –

+0

@PiotrSkotnicki:是的,但为什么没有编译器抱怨呢?如果它不正确,该代码如何编译? –

+3

您可能需要初始化参数,默认值为'summable initial_value = summable()' –

回答

5

您正处在正确的轨道上。对于std::string,值0nullptr相同,并匹配采用const char*的构造函数。

但是,将空指针传递给该构造函数是未定义的行为。未定义的行为意味着任何东西都可能发生。

标准表示:

basic_string(const charT* s, const Allocator& a = Allocator()); 

要求:s点的charT至少traits::length(s) + 1元件的阵列。

效果:构造basic_string类的一个对象,并从 阵列的长度traits::length(s)其第一元件由s指定的charT确定其初始字符串值,如表 指示67.

所以,如果s为空(或0),则它不指向charT的数组,并且前提条件被违反。


而且,顺便说一下,您可以使用summable{}作为参数的默认值。这适用于任何默认的可构造类型。

+0

AHA! ,这说明了这一点,非常感谢。 –