g++和clang++具有不同的容器行为

g++ and clang++ different behaviour with variadic container

本文关键字:clang++ g++      更新时间:2023-10-16

为了练习C++11,我正在使用可变模板。

特别是,我正在使用一种递归可变容器类(onion)和一个返回模板类型数(func())的函数。

我遇到一个案例,clang++(3.5.0)无法编译,而g++(4.9.2)编译并运行时没有问题。

我把它简化为

#include <iostream>
template <typename F, typename ... O>
struct onion;
template <typename F, typename S, typename ... O>
struct onion<F, S, O...>
 {
   F               first;
   onion<S, O...>  others;
 };
template <typename L>
struct onion<L>
 { L  last; };

template <typename ... Args>
std::size_t func (onion<Args...> const &)
 { return sizeof...(Args); }

int main()
 {
   auto o = onion<int, char const *, float> { 23, { "abcd", {34.0f}} };
   std::cout << func(o) << 'n';
   return 0;
 }

clang++(3.5.0)给了我以下编译器错误

test.cpp:28:17: error: no matching function for call to 'func'
   std::cout << func(o) << 'n';
                ^~~~
test.cpp:20:13: note: candidate template ignored: substitution
      failure [with Args = <>]: too few template arguments for class template
      'onion'
std::size_t func (onion<Args...> const &)
            ^     ~~~~~
1 error generated.

g++(4.9.2)编译无问题,运行时输出3

我的问题是:谁是对的?

clang++,给出错误,还是g++,编译?

我补充说,如果我用这种方式重写func()

template <typename X, typename ... Args>
std::size_t func (onion<X, Args...> const &)
 { return 1U + sizeof...(Args); }

或者如果我以这种方式重新定义onion

template <typename ... O>
struct onion;

clang++和g++编译都没有错误。

这看起来像clang 3.5中的一个编译器错误。如果我用trunk版本运行代码,它编译得很好。