首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板难题

模板难题
EN

Stack Overflow用户
提问于 2013-03-08 19:42:23
回答 3查看 797关注 0票数 4

我遇到了一个C++模板难题。我试着把它缩小到最低限度,现在我甚至不确定我想做的事情是否可能。看看下面的代码(在一些.h文件中)。

代码语言:javascript
复制
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函数中,有这样的内容:

代码语言:javascript
复制
//This one works:
A<B1> first;
first.f<int>(5);

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

我从第二部分得到的错误消息是

代码语言:javascript
复制
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

知道问题出在哪里吗?

编辑

为了使问题更加具体,这是我的动机。我希望上面的函数fT=std::tuple<T1, T2>T=std::tuple<T1, T2, T3>T=std::tuple<T1, T2, T3, T4>有专门化,其中tuple中的类型仍然是未绑定的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-08 19:50:29

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

票数 4
EN

Stack Overflow用户

发布于 2013-03-08 20:07:31

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

代码语言:javascript
复制
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
{
}

如果我把它改成

代码语言:javascript
复制
template<>
template<typename S>
void A<B2<int>>::f(S x)
{
}

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

代码语言:javascript
复制
second.f<B2<int>>(5);

这将S设置为B2<int>,函数期望参数为S x,但整数5不能转换为该类型。改为:

代码语言:javascript
复制
B2<int> x;
second.f<B2<int>>(x);

它也同样有效。

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

考虑到您的编辑:我认为您尝试为T=std::tuple<...>专门化的事实已经指明了方向:TA的模板参数,这就是您应该专门化的内容。也许是这样:

代码语言:javascript
复制
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...
};
票数 4
EN

Stack Overflow用户

发布于 2013-03-08 19:46:29

如果要将另一个模板传递给模板,则必须使用https://stackoverflow.com/questions/213761/what-are-some-uses-of-template-template-parameters-in-c,因此A<>模板如下所示:

代码语言:javascript
复制
template<typename T>
class A
{
public:
    template<template <typename> class H, typename S>
    void f(H<S> x);
};

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15301981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档