2012-11-09 26 views
6
template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
} 

这将在最近的g ++编译器上打印115。显然,T被推断为一个数组(而不是指针)。这种行为是否由标准保证?我有点惊讶,因为下面的代码打印了指针的大小,我认为auto的行为完全像模板参数演绎?字符串文字的模板参数推导

int main() 
{ 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 
+1

不要现在为前者,但后者并不意外。字符串文字是数组,不是吗? – Tomek

+2

对于读这个的人不知道:你不能通过值传递数组(它们衰减为指针),但是你确实可以传递一个对数组的引用。在这里,'const T&'成为一个数组的引用,所以'sizeof'给出数组的大小。 –

+1

Martinho的答案涵盖了主要问题。对于保证的行为,14.8.2.1/2:“如果'P'不是引用类型:如果'A'是一个数组类型,则使用由数组到指针标准转换产生的指针类型来代替'A'用于类型推导; ...“其中'P'是模板函数的函数参数的类型,可以涉及一个或多个模板参数,'A'是函数调用中使用的表达式的类型。 – aschepler

回答

8

auto行为完全像模板参数推导。完全像T

比较:

template<typename T> 
void print_size(T x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 4 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 

有了这个:

template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
    const auto& x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 115 
} 

不完全是,但是这不是极端案例之一。

+0

愚蠢的我。感谢您解除窗帘:) – fredoverflow

+0

因为当然,您不能将C风格的数组作为C++中的值传递。 – Yakk

+0

@Yakk:的确,这会破坏C兼容性。 C没有引用,所以现在没有任何行为可以打破。 – MSalters