从另一个专业继承的模板可以是循环依赖还是 clang 的错误
Can template inheritance from its another specialization be a circular dependency or is it a clang's bug
考虑以下代码:
#include <iostream>
#include <utility>
#include <tuple>
template <class TargetIndices, class SourceIndices>
struct assign;
template <size_t... TargetIs, size_t... SourceIs>
struct assign<std::index_sequence<TargetIs...>, std::index_sequence<SourceIs...>>: assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>... {
template <class TargetTuple, class SourceTuple>
assign(TargetTuple &target, const SourceTuple &source): assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>(target, source)... { }
};
template <size_t FirstTI, size_t FirstSI>
struct assign<std::index_sequence<FirstTI>, std::index_sequence<FirstSI>> {
template <class TargetTuple, class SourceTuple>
assign(TargetTuple &target, const SourceTuple &source) {
std::get<FirstTI>(target) = std::get<FirstSI>(source);
}
};
int main() {
std::tuple<int, int, int> t1 = std::make_tuple(0,0,0), t2 = std::make_tuple(1,2,3);
assign<std::index_sequence<0,2>, std::index_sequence<2,0>>(t1, t2);
std::cout << std::get<0>(t1) << " " << std::get<1>(t1) << " " << std::get<2>(t1) << std::endl;
}
clang++ 声明在继承中存在循环依赖。 g++ 编译它没有任何问题。哪个编译器是正确的?
它看起来像一个 clang bug。
最小复制如下:
template <int...> struct q {};
template <int... Is> using w = q<Is...>;
template <class T>
struct a;
template <int F>
struct a<w<F>> {};
template <int... T>
struct a<w<T...>>: a<w<T>>... {}; // g++ OK, clang++ breaks
模板别名在这里必不可少。当最后一行使用原始模板而不是模板别名时,编译:
struct a<q<T...>>: a<q<T>>... {}; // g++, clang++ OK
考虑以下代码:
#include <iostream>
#include <utility>
#include <tuple>
template <class TargetIndices, class SourceIndices>
struct assign;
template <size_t... TargetIs, size_t... SourceIs>
struct assign<std::index_sequence<TargetIs...>, std::index_sequence<SourceIs...>>: assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>... {
template <class TargetTuple, class SourceTuple>
assign(TargetTuple &target, const SourceTuple &source): assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>(target, source)... { }
};
template <size_t FirstTI, size_t FirstSI>
struct assign<std::index_sequence<FirstTI>, std::index_sequence<FirstSI>> {
template <class TargetTuple, class SourceTuple>
assign(TargetTuple &target, const SourceTuple &source) {
std::get<FirstTI>(target) = std::get<FirstSI>(source);
}
};
int main() {
std::tuple<int, int, int> t1 = std::make_tuple(0,0,0), t2 = std::make_tuple(1,2,3);
assign<std::index_sequence<0,2>, std::index_sequence<2,0>>(t1, t2);
std::cout << std::get<0>(t1) << " " << std::get<1>(t1) << " " << std::get<2>(t1) << std::endl;
}
clang++ 声明在继承中存在循环依赖。 g++ 编译它没有任何问题。哪个编译器是正确的?
它看起来像一个 clang bug。
最小复制如下:
template <int...> struct q {};
template <int... Is> using w = q<Is...>;
template <class T>
struct a;
template <int F>
struct a<w<F>> {};
template <int... T>
struct a<w<T...>>: a<w<T>>... {}; // g++ OK, clang++ breaks
模板别名在这里必不可少。当最后一行使用原始模板而不是模板别名时,编译:
struct a<q<T...>>: a<q<T>>... {}; // g++, clang++ OK