Следующий код дает совершенно разные результаты при компиляции с г ++ или лязгом ++. Извините за длинный пример, но я не смог сделать его короче.г ++ и лязг различное поведение с рекурсивной VARIADIC создания шаблона BITSET (возможно GCC ошибка?)
Программа должна назначить конкретную позицию бит конкретному типу, а затем построить 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;
}
- г ++ 4.8.2 принты -----:
00000000000000000000000000000001
- лязгом ++ SVN печатает:
00000000000000000000000000001111
(как и ожидалось)
только флаг компиляции -std=c++11
,
Что происходит? Я представляю неопределенное поведение? Является ли g ++ неправильным?
Относительно вашего заявления о том, что «Только флаг компиляции -std = C++ 11»: хотя в этом случае не может быть ни одного, когда у вас есть проблема, всегда включайте столько предупреждений, сколько сможете. –
Хотя я не знаю, является ли это ошибкой, эта программа не «назначает конкретную позицию бита определенному типу во время компиляции», если только из-за правила as-if. Он работает во время инициализации. Вы не можете использовать функции non-constexpr во время компиляции. – zch
@zch: Да, извините, я использовал неправильный термин. Фиксация OP. –