【问题标题】:Template template parameters and variadic templates with gcc 4.4带有 gcc 4.4 的模板模板参数和可变参数模板
【发布时间】:2012-01-20 19:50:36
【问题描述】:

我在 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 &lt;typename T, typename... Args&gt; class C 的语法是否正确?

这给出了错误

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

这似乎类似于问题Variadic template templates and perfect forwarding。这个问题表明这是一个 gcc 错误,但也许我错误地认为这些问题是关于同一件事的。

请温柔一点。我对可变参数模板的了解还不到 12 小时;我只是想重写一些旧的 C++ 代码以减少重复。我也有一段时间没有做任何 C++ 了。如果有解决方法,请告诉我。谢谢。

编辑:Ise Wisteria 在Variadic template templates and perfect forwarding 的 cmets 中建议的解决方法对我有用,这表明这是同一个错误。当然,我现在 (a) 想知道这种解决方法有多脆弱,(b) 它为什么起作用,以及是什么促使 Ise 想到它。 虽然我猜只有一诚可以回答最后一点。 :-)

【问题讨论】:

  • 代码在 g++ 4.7 上编译。应该是一个错误。
  • @KennyTM:谢谢。这意味着我不需要报告,对吧?
  • 那么,您希望这个问题发生什么?关闭为重复?也许回答你自己的问题? :) 这不能保持原样。
  • @Xeo:那么,在您看来,这绝对是链接问题的副本?如果是这样,我没有强烈的感情。如果我回答然后接受我的回答可以吗?除非你或其他人愿意。 :-) 如果它关闭了,搜索的人是否仍然可以看到它?
  • 不完全一样,但问题是一样的,答案也是一样。不过我真的不在乎,不妨继续回答你自己的问题。 :)

标签: c++ c++11 variadic-templates template-templates


【解决方案1】:

正如编辑中所讨论的,我的问题似乎与链接问题Variadic template templates and perfect forwarding 相同的错误。特别是,链接中给出的解决方法也适用于我的情况。修改后的代码如下:

#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>();
}

【讨论】:

    【解决方案2】:

    我不认为可变参数模板参数可以匹配 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>();
    }
    

    【讨论】:

    • 不,可变参数模板可以显式匹配非可变参数模板。
    • 嗯,这是一个错误。我说的是标准所说的。 “我不认为可变参数模板参数可以匹配非可变参数”似乎表明您认为这是一般情况。
    • @Xeo:很公平。我将编辑答案以反映您的观点。
    猜你喜欢
    • 2014-09-08
    • 1970-01-01
    • 2016-12-01
    • 2014-04-12
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    相关资源
    最近更新 更多