2017-01-03 25 views
7
#include <iostream> 
using namespace std; 

void f(const char* arg) 
{ 
    cout << "arg is a pointer" << endl; 
} 

template<size_t N> 
void f(const char (&arg)[N]) 
{ 
    cout << "arg is an array." << endl; 
} 

int main() 
{ 
    f(""); 
} 

我的編譯器是叮噹3.8。爲什麼clang將字符串字面量當作指針而不是數組?

的輸出是:

arg是指向

然而,根據cppreference.com

類型的前綴的字符串文字的是爲const char [] 。

爲什麼重載分辨率不像預期的那樣表現?

+2

等效的例子,但抽象了模板:http://melpon.org/wandbox/permlink/0nGenu5Ysj40wS8u –

+0

[密切相關](https://stackoverflow.com/questions/16708307/is-it-possible-to -legally-overload-a-string-literal-and-const-char),可能是重複。你怎麼看? –

回答

8

它不會像預期的那樣,你只需要調整您的期望;-)

const char[1]const char (&)[1]是不同的類型。

轉換爲const char*(數組到指針轉換)和const (&char)[1](標識轉換)都被認爲是完全匹配,但非模板比模板匹配得更好。

如果你寫一個非模板尺寸專用的過載,

void f(const char (&arg)[1]) 

,該函數調用是不明確的,你會得到一個錯誤。

+2

太慢了。 :(僅供參考,N4141的表12中列出了相關的標準 –

1

@ molbdnilo的回答是正確的。添加一個細節:你的直覺是正確的,編譯器寧願通過調用模板來避免數組到指針的轉換。根據[over.ics.rank]§13.3.3.2/ 3.2.1,左值轉換(左值到右值,數組到指針和函數到指針)在過載排名中被明確忽略。

有一個workaround:添加一個假的volatile恢復過載偏好的平衡。在使用參數之前,請確保將其刪除const_cast

相關問題