2011-03-15 27 views
3

也許我不知道如何搜索,但事實上我找不到任何人在討論這個問題。C++模板參數變化引用指針

我有一個結構,有非類型參數取決於類型參數。

template< 
    typename SpecType, 
    SpecType NonType > 
struct Struct 
//... 

SpecType是一個參照本發明的指針(const char *&,例如)NonType行爲就好像它是實際的專門參數的地址,而不是參考。 更令人驚訝的是,如果我明確地投到SpecType,一切都按預期工作!

IBM說了一些關於轉換爲數組和函數的指針,但我不明白它與我的疑問有關。

當我創建沒有嵌入模板類型的結構(S1S2)時,同樣的事情不會發生。

當然,我可以把它改成:

template< 
    typename SpecType, 
    SpecType &NonType > 

但它無法解釋我所看到的。 任何人都可以請一個深深的(或愚蠢的,如果這是我的愚蠢)的解釋?


下面的例子是有點可拓,但看着它的輸出,我認爲我的問題會更清楚:

#include <iostream> 
#include <typeinfo> 

using namespace std; 


void f1(const char **p) 
{ 
    cout << "---------------------------------------------" << endl; 
    cout << "f1(const char **p): p = \"" << p << "\"" << endl; 
} 

void f1(const char *p) 
{ 
    cout << "---------------------------------------------" << endl; 
    cout << "f1(const char *p): p = \"" << p << "\"" << endl; 
} 

void f1(const int **p) 
{ 
    cout << "---------------------------------------------" << endl; 
    cout << "f1(const int **p): p = \"" << p << "\"" << endl; 
} 

void f1(const int *p) 
{ 
    cout << "---------------------------------------------" << endl; 
    cout << "f1(const int *p): p = \"" << p << "\"" << endl; 
} 

template< 
    typename SpecType, 
    SpecType NonType > 
struct Struct 
{ 
    void f() 
    { 
     cout << "---------------------------------------------" << endl; 
     cout << "SpecType is " << typeid(SpecType).name() << endl; 
     cout << "NonType is " << typeid(NonType).name() << endl; 
     cout << "NonType = \"" << NonType << "\"" << endl; 
     cout << "(SpecType)NonType = \"" << (SpecType)NonType << "\"" << endl; 
     cout << "*NonType = \"" << *NonType << "\"" << endl; 
     cout << "*NonType[ 0 ] = \"" << **NonType << "\"" << endl; 

     f1(NonType); 
    } 
}; 

template< const char *&P > 
struct S1 
{ 
    void f() 
    { 
     cout << "---------------------------------------------" << endl; 
     cout << "&P = \"" << &P << "\"" << endl; 
     cout << "P = \"" << P << "\"" << endl; 
     cout << "*P = \"" << *P << "\"" << endl; 

     f1(P); 
    } 
}; 

template< const char **P > 
struct S2 
{ 
    void f() 
    { 
     cout << "---------------------------------------------" << endl; 
     cout << "P = \"" << P << "\"" << endl; 
     cout << "*P = \"" << *P << "\"" << endl; 
     cout << "*P[ 0 ] = \"" << **P << "\"" << endl; 

     f1(P); 
    } 
}; 

const char * const_pname = "name"; 

const int pint[] = { 42, 51 }; 
const int *const_pint = pint; 

int main() 
{ 
    cout << "=============================================" << endl; 
    cout << "const_pname = " << const_pname << endl; 
    cout << "@const_pname = 0x" << hex << (unsigned long)const_pname << dec << endl; 
    cout << "&const_pname = 0x" << hex << (unsigned long)&const_pname << dec << endl; 

    cout << "=============================================" << endl; 
    cout << "Struct< const char *&, const_pname > constpTtname" << endl; 
    Struct< const char *&, const_pname > constpTtname; 
    constpTtname.f(); 

    cout << "=============================================" << endl; 
    cout << "Struct< const int *&, const_pint > constpTtint" << endl; 
    Struct< const int *&, const_pint > constpTtint; 
    constpTtint.f(); 

    cout << "=============================================" << endl; 
    cout << "S1<const_pname> s1" << endl; 
    S1<const_pname> s1; 
    s1.f(); 

    cout << "=============================================" << endl; 
    cout << "S2< &const_pname > s2" << endl; 
    S2< &const_pname > s2; 
    s2.f(); 

    return 0; 
} 

輸出是:

$ ./nontype_mutant 
============================================= 
const_pname = name 
@const_pname = x401624                 
&const_pname = 0x601e18                 
=============================================            
Struct< const char *&, const_pname > constpTtname          
---------------------------------------------            
SpecType is PKc                   
NonType is PKc                    
NonType = "[email protected]"                    
(SpecType)NonType = "name"                
*NonType = "name"                   
*NonType[ 0 ] = "n"                  
---------------------------------------------            
f1(const char *p): p = "[email protected]"                
=============================================            
Struct< const int *&, const_pint >  constpTtint          
---------------------------------------------            
SpecType is PKi                   
NonType is PKi                    
NonType = "0x601e20"                  
(SpecType)NonType = "0x4017a8"               
*NonType = "0x4017a8"                  
*NonType[ 0 ] = "42"                  
---------------------------------------------            
f1(const int *p): p = "0x601e20"               
=============================================            
S1<const_pname>  s1 
--------------------------------------------- 
&P = "0x601e18" 
P = "name" 
*P = "n" 
--------------------------------------------- 
f1(const char *p): p = "name" 
============================================= 
S2< &const_pname >  s2 
--------------------------------------------- 
P = "0x601e18" 
*P = "name" 
*P[ 0 ] = "n" 
--------------------------------------------- 
f1(const char **p): p = "0x601e18" 
+0

什麼編譯器? – 2011-03-15 19:25:30

+0

@Ben Voigt:g ++(GCC)4.4.5 20101112(Red Hat 4.4.5-2)和g ++(GCC)4.3.2 20081105(Red Hat 4.3.2-7)。 – j4x 2011-03-15 19:31:54

回答

1

我已經試圖使用三個編譯器編譯您的代碼,其中兩個具有非常類似的行爲,並提供以下消息(大約):

test.cpp:44:41: error: indirection requires pointer operand ('int' invalid) 
     cout << "*NonType[ 0 ] = \"" << **NonType << "\"" << endl; 
             ^~~~~~~~~ 
test.cpp:93:18: note: in instantiation of member function 'Struct<const char *&, const_pname>::f' requested here 
    constpTtname.f(); 
       ^
test.cpp:44:41: error: indirection requires pointer operand ('int' invalid) 
     cout << "*NonType[ 0 ] = \"" << **NonType << "\"" << endl; 
             ^~~~~~~~~ 
test.cpp:98:17: note: in instantiation of member function 'Struct<const int *&, const_pint>::f' requested here 
    constpTtint.f(); 
       ^
2 errors generated. 

錯誤消息似乎對我來說是正確的和不言而喻的。這是使用clang的結果。 Comeau的基於EDG的編譯器是另一個給出與此非常相似的消息的編譯器。

g ++編譯它(我相信不正確),並給出了類似於你報告的輸出。

+0

「$ g ++ -Wall nontype_mutant.cpp -o nontype_mutant」給了我沒有錯誤。我從我自己的帖子中重新編譯並重新運行這個例子,以確保我沒有做錯任何事情。您可以安全地評論第44行,相關問題仍然存在。請在我的帖子中注意,問題在於引用像一個指針,而不是一個間接編譯錯誤。 – j4x 2011-03-15 19:39:36