代码之家  ›  专栏  ›  技术社区  ›  Timothy Shields

模板Conundrum

  •  4
  • Timothy Shields  · 技术社区  · 12 年前

    我遇到了一个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<T1, T2> , T=std::tuple<T1, T2, T3> T=std::tuple<T1, T2, T3, T4> ,其中 tuple 仍然未绑定。

    3 回复  |  直到 12 年前
        1
  •  4
  •   Paul Michalik    12 年前

    您正在尝试对成员函数模板进行部分专门化。恐怕这是不可能的。。。

        2
  •  4
  •   Daniel Frey    12 年前

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

    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<int> 函数需要一个参数 S x -但是整数 5 无法转换为该类型。将其更改为:

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

    它也同样有效。

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


    想想你的编辑:我认为你试图专注于 T=std::tuple<...> 已经指明了方向: T 是的模板参数 A 那个 这是你应该擅长的。也许是这样的:

    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
  •  1
  •   Community CDub    7 年前

    如果要将另一个模板传递给某个模板,则必须使用 template template parameters ,所以你的A<>模板如下所示:

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

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

    如果您的原始模板没有采用这样的参数类型,我认为您不能专门处理模板模板参数。