【问题标题】:Template Conundrum模板难题
【发布时间】:2013-03-08 19:42:23
【问题描述】:

我遇到了一个 C++ 模板难题。我试图将它削减到最低限度,现在我什至不确定我想要做的事情是否可行。看看下面的代码(在一些 .h 文件中)。

template<typename T>
class A
{
public:
    template<typename S>
    void f(S x);
};

class B1 { };

template<typename S>
class B2 { };

//This one works:
template<>
template<typename S>
void A<B1>::f(S x)
{
}    

//This one does not work:
template<>
template<typename S>
void A<B2<S>>::f(S x)
{
}

在我的 main 函数中,我有这样的东西:

//This one works:
A<B1> first;
first.f<int>(5);

//This one does not work:
A<B2<int>> second;
second.f<int>(5);

由于第二部分,我得到的错误消息是

error C3860: template argument list following class
             template name must list parameters in the
             order used in template parameter list

error C3855: 'A<T>': template parameter 'T' is
             incompatible with the declaration

知道问题出在哪里吗?


编辑

为了使问题更具体,这是我的动机。我希望上面的函数f 具有T=std::tuple&lt;T1, T2&gt;T=std::tuple&lt;T1, T2, T3&gt;T=std::tuple&lt;T1, T2, T3, T4&gt; 的特化,其中tuple 中的类型仍然未绑定。

【问题讨论】:

  • 你想用这个做什么?也许有更好的方法。
  • 这是你想要的吗? stacked-crooked.com/…
  • @Pubby 我在最后添加了一个带有动机的部分。
  • 回复:您的编辑:那将是函数模板的部分专业化。不可能。您可以通过将函数委托给类模板来模拟它。或者普通的重载怎么样?
  • @TimothyShields 只是用template&lt;typename... T&gt; void f(std::tuple&lt;T...&gt;); 超载了吗?

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


【解决方案1】:

您正在尝试对成员函数模板进行部分特化。那是不可能的,恐怕……

【讨论】:

    【解决方案2】:

    您的代码有两个问题。首先,第二个专业化是非法的,因为

    template<> // parameters useable for the specialization of A you refer to
               // since it is a function, no partial specialization is allowed.
    template<typename S> // parameters for the function's parameters
    void A<B2<S>>          // S can not be used here!
                 ::f(S x)  // only here
    {
    }
    

    如果我把它改成

    template<>
    template<typename S>
    void A<B2<int>>::f(S x)
    {
    }
    

    它起作用了,现在第二个问题暴露了:

    second.f<B2<int>>(5);
    

    这会将S 设置为B2&lt;int&gt;,并且该函数需要一个参数S x - 但整数5 无法转换为该类型。将其更改为:

    B2<int> x;
    second.f<B2<int>>(x);
    

    它也能正常工作。

    请注意,这可能无法解决您试图解决的问题,它只是解释了发生了什么。


    考虑您的编辑:我认为您尝试专注于 T=std::tuple&lt;...&gt; 的事实已经指明了方向:TA 的模板参数, 是您应该做的专攻。可能是这样的:

    template< typename T >
    class F // used to implement f(), so you can specialize
            // just F/f() instead of the whole class A
    {
      void f(T x) { /* default impl */ }
    };
    
    template< typename T1, typename T2 >
    class F< std::tuple< T1, T2 > >
    {
      void f(T1 x, T2 y) { /* special impl */ }
    };
    
    template< typename T >
    class A : public F< T >
    {
        // ...other stuff...
    };
    

    【讨论】:

      【解决方案3】:

      如果你想将另一个模板传递给一个模板,你必须使用template template parameters,所以你的 A 模板看起来像这样:

      template<typename T>
      class A
      {
      public:
          template<template <typename> class H, typename S>
          void f(H<S> x);
      };
      

      现在您可以将模板传递给您的模板。

      如果您的原始模板没有采用这种参数类型,我认为您不能专注于模板模板参数。

      【讨论】:

      • 我现在正在研究这个......会回复你它是否适合我。看起来很有希望。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多