Pri*_*tic 12 c++ templates clang c++11
我根据两种类型编写了一个类模板,根据模板参数分配了一个唯一的索引:
template<typename SK,typename T>
struct Component {
static uint const index;
};
Run Code Online (Sandbox Code Playgroud)
期望是每个新类型index增加:
Component<X,A>::index; // 0
Component<X,B>::index; // 1
Component<Y,A>::index; // 0
Component<Y,B>::index; // 1
// ...etc
Run Code Online (Sandbox Code Playgroud)
分配索引的完整代码如下:
using uint = unsigned int;
template<typename SK,typename T>
struct Component
{
static uint const index;
};
template<typename SK>
class ComponentCount
{
template<typename CSK,typename CT>
friend struct Component;
private:
template<typename T>
static uint next() {
return ComponentCount<SK>::get_counter();
}
static uint get_counter()
{
static uint counter = 0;
return counter++;
}
};
Run Code Online (Sandbox Code Playgroud)
这在GCC(5.1)和MSVC中的预期效果如下:
// global scope
struct X {};
struct Y {};
int main()
{
// function scope
struct Z{};
uint x0 = Component<X,int>::index;
uint x1 = Component<X,double>::index;
uint x2 = Component<X,double>::index;
uint x3 = Component<X,std::string>::index;
uint x4 = Component<X,int>::index;
uint x5 = Component<X,int>::index;
std::cout << x0 << ", " << x1 << ", " << x2 << ", "
<< x3 << ", " << x4 << ", " << x5 << std::endl;
uint y0 = Component<Y,int>::index;
uint y1 = Component<Y,double>::index;
uint y2 = Component<Y,double>::index;
uint y3 = Component<Y,std::string>::index;
uint y4 = Component<Y,int>::index;
uint y5 = Component<Y,int>::index;
std::cout << y0 << ", " << y1 << ", " << y2 << ", "
<< y3 << ", " << y4 << ", " << y5 << std::endl;
uint z0 = Component<Z,int>::index;
uint z1 = Component<Z,double>::index;
uint z2 = Component<Z,double>::index;
uint z3 = Component<Z,std::string>::index;
uint z4 = Component<Z,int>::index;
uint z5 = Component<Z,int>::index;
std::cout << z0 << ", " << z1 << ", " << z2 << ", "
<< z3 << ", " << z4 << ", " << z5 << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是
0, 1, 1, 2, 0, 0
0, 1, 1, 2, 0, 0
0, 1, 1, 2, 0, 0
Run Code Online (Sandbox Code Playgroud)
但是对于Clang(3.6.1),输出不同:
0, 1, 1, 2, 0, 0
0, 1, 1, 2, 0, 0
5, 2, 2, 3, 5, 5
Run Code Online (Sandbox Code Playgroud)
具体来说,为函数本地类型(即'Z')生成的索引做了一些奇怪的事情.就像它们每次Component<Z,...>调用时增加和重新分配索引一样.
为什么会这样?这是编译器错误吗?使用带有模板的函数本地类型时是否有任何特殊注意事项(后C++ 11)?
这里有一个完整的例子:http: //coliru.stacked-crooked.com/a/7fcb989ae6eab476
==编辑==
我决定将这个问题发布给clang的bugtracker,所以如果有其他人遇到这个:
这对我来说看起来像是一个错误。我不知道 C++11 规则应该对函数局部类型和全局类型产生影响。
如果转储汇编器,您会注意到 while forX和Y值实际上被计算,因为Z它们是预先计算的。根本不生成用于计数器静态变量初始化的保护变量。
.Ltmp87:
#DEBUG_VALUE: main:z5 <- 5
#DEBUG_VALUE: main:z4 <- 5
#DEBUG_VALUE: main:z3 <- 3
#DEBUG_VALUE: main:z2 <- 2
#DEBUG_VALUE: main:z1 <- 2
#DEBUG_VALUE: main:z0 <- 5
.loc 6 54 5 # main.cpp:54:5
movl std::cout, %edi
movl $5, %esi
.loc 6 74 5 # main.cpp:74:5
callq std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned int)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
215 次 |
| 最近记录: |