(抱歉,我刚刚注意到这个问题被标记为c,而不是c++。也许我的回答毕竟与这个问题不太相关!)
字符串字面量不完全是const 或not-const,字面量有一个特别奇怪的规则。
(总结:文字可以通过引用数组作为foo( const char (&)[N]),不能作为非常量数组。它们更喜欢衰减到const char *。到目前为止,这使得它们看起来像是 const。但是有一个特殊的旧规则允许文字衰减到 char *。请参阅下面的实验。)
(在使用 -std=gnu++0x 在 clang3.3 上进行的实验之后。也许这是 C++11 问题?还是特定于 clang?无论哪种方式,都会发生一些奇怪的事情。)
起初,文字似乎是const:
void foo( const char * ) { std::cout << "const char *" << std::endl; }
void foo( char * ) { std::cout << " char *" << std::endl; }
int main() {
const char arr_cc[3] = "hi";
char arr_c[3] = "hi";
foo(arr_cc); // const char *
foo(arr_c); // char *
foo("hi"); // const char *
}
这两个数组的行为符合预期,证明foo 能够告诉我们指针是否为const。然后"hi" 选择const 版本的foo。所以看起来这就解决了:文字是const ...不是吗?
但是,如果你删除了void foo( const char * ),它就会变得很奇怪。首先,对foo(arr_c) 的调用在编译时失败并出现错误。这是意料之中的。但是文字调用 (foo("hi")) 通过非常量调用工作。
因此,字面量比arr_c“更常量”(因为它们更喜欢衰减到const char *,不像arr_c。但字面量比arr_cc“更小”,因为它们愿意衰减到char * 如果需要。
(当 Clang 衰减到 char * 时会发出警告)。
但是腐烂的呢?为简单起见,让我们避免它。
让我们通过引用将数组放入 foo 中。这给了我们更“直观”的结果:
void foo( const char (&)[3] ) { std::cout << "const char (&)[3]" << std::endl; }
void foo( char (&)[3] ) { std::cout << " char (&)[3]" << std::endl; }
和以前一样,字面量和 const 数组 (arr_cc) 使用 const 版本,arr_c 使用非 const 版本。如果我们删除foo( const char (&)[3] ),那么foo(arr_cc); 和foo("hi"); 都会出现错误。简而言之,如果我们避免指针衰减并改用数组引用,文字的行为就好像它们是const。
模板?
在模板中,系统将推断出const char * 而不是char *,而您对此“卡住”了。
template<typename T>
void bar(T *t) { // will deduce const char when a literal is supplied
foo(t);
}
所以基本上,文字始终表现为const,除非您直接使用文字初始化char *。