模板模板参数和可变模板与gcc 4.4

Template template parameters and variadic templates with gcc 4.4

本文关键字:gcc 参数      更新时间:2023-10-16

我在Debian squeeze上使用gcc 4.4。考虑下面的代码:

#include <map>
#include <string>
using std::map;
using std::string;
// Args lets the user specify additional explicit template arguments
template <typename T,
      template <typename T, typename... Args> class C,
      typename... Args>
C<T, Args...> foo()
{
  C<T, Args...> x;
  return x;
}
int main(void)
{
  map<string, int> a = foo<string, map, int>();
}

因此,这里的想法是T匹配string, C匹配map,模板参数包Args匹配int。我可能有一些语法错误,如果有,请纠正。特别是,如果希望class C中的第一个模板参数与T匹配,其余参数与模板参数包Args匹配,那么template <typename T, typename... Args> class C的语法是否正确?

给出错误

In function 'int main()':
post.cc:18: error: no matching function for call to 'foo()'

这似乎类似于可变模板模板和完美转发的问题。这个问题表明这是一个gcc错误,但也许我认为这些问题是关于同一件事的错误。

请温柔一点。我对可变模板的了解还不到12个小时;我只是试图重写一些旧的c++代码,以减少重复。我也有一段时间没有使用c++了。如果有变通办法,请让我知道。谢谢。

编辑:在可变模板模板和伊势紫藤的完美转发的评论中建议的解决方案对我有效,这表明这是同一个错误。当然,我现在是(a)想知道这个解决方法有多脆弱,(b)为什么它有效,是什么促使我想到它。不过我想只有伊势能回答最后一点。: -)

正如编辑中所讨论的,我的问题似乎与链接的问题一样,可变模板模板和完美转发。特别是,在链接中给出的解决方法也适用于我的情况。修改后的有效代码如下:

#include <map>
#include <string>
using std::map;
using std::string;
template <typename T,
      template <typename T, typename... Args> class C,
      typename... Args>
struct X
{
  typedef C<T, Args...> type;
};
template <typename T,
      template <typename T, typename... Args> class C,
      typename... Args>
typename X<T, C, Args...>::type foo()
{
  C<T, Args...> x;
  return x;
}
int main(void)
{
  map<string, int> a = foo<string, map, int>();
}

我不认为可变参数模板形参可以匹配g++4.4中的非可变参数,所以你需要用一个非可变版本重载你的foo函数。

还要记住,map实际上有两个以上的模板形参,因此也不会匹配新的foo函数。

这个添加到你的例子应该澄清:

#include <map>
#include <string>
using std::map;
using std::string;
// Args lets the user specify additional explicit template arguments
template <typename T,
          template <typename T, typename... Args> class C,
          typename... Args>
C<T, Args...> foo() {
  C<T, Args...> x;
  return x;
}
template<typename T, template<typename, typename> class C, typename Arg>
C<T, Arg> foo() {
  return C<T, Arg>();
}
template<typename T, typename... Args> class A {};
template<typename T, typename Arg> class B {};
int main(void) {
  map<string, int> a = foo<string, map, int>(); // fails.
  A<string, int> x = foo<string, A, int>();
  B<string, int> y = foo<string, B, int>();
}