【发布时间】:2011-03-15 18:25:24
【问题描述】:
也许我不知道如何搜索,但事实上我找不到任何人在谈论这个。
我有一个结构体,它有一个 非类型 参数,该参数依赖于一个 type 参数。
template<
typename SpecType,
SpecType NonType >
struct Struct
//...
当SpecType 是对指针的引用(例如const char *&)时,NonType 的行为就好像它是实际专用参数的地址,而不是引用。
更令人惊讶的是,如果我将NonType 明确转换为SpecType,一切都会按预期进行!
IBM 说了一些关于转换为数组和函数指针的事情,但我不明白这与我的疑问有关。
当我创建没有嵌入模板类型(S1 和 S2)的结构时,不会发生同样的事情。
当然可以改成:
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 = "$@"
( SpecType )NonType = "name"
*NonType = "name"
*NonType[ 0 ] = "n"
---------------------------------------------
f1( const char *p ): p = "$@"
=============================================
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"
【问题讨论】:
-
@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)。跨度>