gpt4 book ai didi

c++ - g++ 和 clang 使用递归可变参数模板位集创建的不同行为(可能是 gcc 错误?)

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:19:27 28 4
gpt4 key购买 nike

以下代码在使用 g++clang++ 编译时会产生截然不同的结果。很抱歉这个例子太长了,但我没能缩短它。

程序应将特定位位置分配给特定类型,然后构建包含多个类型位的 std::bitset

#include <bitset>
#include <iostream>

using namespace std;
using Bts = bitset<32>;

int getNextId() { static int last{0}; return last++; }

template<class T> struct IdStore{ static const int bitIdx; };
template<class T> const int IdStore<T>::bitIdx{getNextId()};

template<class T> void buildBtsHelper(Bts& mBts) {
mBts[IdStore<T>::bitIdx] = true;
}
template<class T1, class T2, class... A>
void buildBtsHelper(Bts& mBts) {
buildBtsHelper<T1>(mBts); buildBtsHelper<T2, A...>(mBts);
}
template<class... A> Bts getBuildBts() {
Bts result; buildBtsHelper<A...>(result); return result;
}

template<class... A> struct BtsStore{ static const Bts bts; };
template<class... A> const Bts BtsStore<A...>::bts{getBuildBts<A...>()};
template<> const Bts BtsStore<>::bts{};

template<class... A> const Bts& getBtsStore() {
return BtsStore<A...>::bts;
}

struct Type1 { int k; };
struct Type2 { float f; };
struct Type3 { double z; };
struct Type4 { };

int main()
{
cout << getBtsStore<Type1, Type2, Type3, Type4>() << endl;
return 0;
}
  • g++ 4.8.2 打印-----:00000000000000000000000000000001
  • clang++ SVN 打印:0000000000000000000000000001111 (如预期)

只有编译标志是-std=c++11

发生了什么?我是否引入了未定义的行为? g++ 错了吗?

最佳答案

您的代码依赖于两个声明的初始化顺序:

template<class T> const int IdStore<T>::bitIdx{getNextId()};

template<class... A> const Bts BtsStore<A...>::bts{getBuildBts<A...>()};
// getBuildBts uses IdStore<T>::bitIdx as indexes to assign

如果所有 IdStore<T>::bitIdx初始化发生在 BtsStore<A...>::bts 之前然后你得到你预期的行为。如果所有的都发生在BtsStore<A...>::bts之后然后你得到 g++ 行为。标准允许两种顺序:

3.6.2 Initialization of non-local variables

2 (...) Dynamic initialization of a non-local variable with static storage duration is either ordered or unordered. Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization.

关于c++ - g++ 和 clang 使用递归可变参数模板位集创建的不同行为(可能是 gcc 错误?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19563891/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com