以下内容将类型转换F
应用于C
类型的列表E...
:
template <template <typename...> class F, typename P> struct apply_t;
template <
template <typename...> class F,
template <typename...> class C, typename... E
> struct apply_t <F, C <E...> > { typedef C <F <E>...> type; };
template <template <typename...> class F, typename P>
using apply = typename apply_t<F, P>::type;
现在,给出这个输入:
template <typename T> using map1 = T*;
template <typename T> using map2 = const T;
template <typename T> using map3 = const T*;
我在gcc 4.8.1中得到以下输出,例如使用std::tuple
:
apply <map1, tuple <int, char> > // -> tuple <int*, char*> (OK)
apply <map2, tuple <int, char> > // -> tuple <int, char>
// (tuple <const int, const char> expected)
apply <map3, tuple <int, char> > // -> tuple <const int*, const char*> (OK)
我可以使用调用static_assert()
的实用程序模板函数来查看输出类型。
我尝试过各种各样的组合。当作为const T
的输入类型地图给出时,除了地图apply
之外,一切都有效。但如果我将其嵌入apply
的定义,即typedef C <const E...> type
,仍然可以正常工作。
另一方面,一切都按照预期的方式运作。我可能会遗漏一些东西,但这对我来说似乎是一个gcc bug。
有什么想法吗?
答案 0 :(得分:1)
这是一个完整但缩减的测试用例,您可能希望将其添加到GCC错误报告中(如果您需要编写一个):
template< typename T > using Map = const T;
template< template<typename> class M, typename T >
struct Apply;
template< template<typename> class M, template<typename...> class C, typename... Ts >
struct Apply< M, C<Ts...> > { typedef C<M<Ts>...> type; };
template< typename T > struct A {};
template<typename> void dummy();
int main()
{
dummy< Apply<Map,A<int>>::type >();
}
由于,将无法链接
undefined reference to `void dummy<A<int> >()'
而不是预期的
undefined reference to `void dummy<A<const int> >()'
(我知道这并没有解决问题,但GCC人员可能更喜欢减少测试用例,而不依赖std::tuple
或任何其他标题。)