Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板化类型的模板专门化_C++_Templates_Specialization - Fatal编程技术网

C++ 模板化类型的模板专门化

C++ 模板化类型的模板专门化,c++,templates,specialization,C++,Templates,Specialization,我想用以下函数专门化类模板: template <typename T> class Foo { public: static int bar(); }; 模板 福班 { 公众: 静态int-bar(); }; 该函数没有参数,应根据Foo的类型返回结果。(在这个玩具示例中,我们返回类型的字节数,但在实际应用程序中,我们希望返回一些元数据对象。) 专门化适用于完全指定的类型: // specialization 1: works template <> int

我想用以下函数专门化类模板:

template <typename T>
class Foo
{
public:
    static int bar();
};
模板
福班
{
公众:
静态int-bar();
};
该函数没有参数,应根据Foo的类型返回结果。(在这个玩具示例中,我们返回类型的字节数,但在实际应用程序中,我们希望返回一些元数据对象。) 专门化适用于完全指定的类型:

// specialization 1: works
template <>
int Foo<int>::bar() { return 4; }

// specialization 2: works
template <>
int Foo<double>::bar() { return 8; }

// specialization 3: works
typedef pair<int, int> IntPair;
template <>
int Foo<IntPair>::bar() { return 2 * Foo<int>::bar(); }
//专门化1:有效
模板
int Foo::bar(){return 4;}
//专业2:作品
模板
int Foo::bar(){return 8;}
//专业3:作品
typedef对IntPair;
模板
int Foo::bar(){return 2*Foo::bar();}
但是,我想将其推广到依赖于(其他)模板参数本身的类型。 添加以下专门化会产生编译时错误(VS2005):

//专业化4:错误!
模板
模板
int Foo::bar(){return Foo::bar()+Foo::bar();}

我假设这不是合法的C++,但是为什么?是否有一种优雅的实现这种模式的方法?

它在C++中是完全合法的,它是部分模板特化。
删除
模板
,如果它还不存在,添加显式类模板专门化,它应该在VS2005上编译(但不在VC6中)

//显式类模板专门化
模板
福班
{
公众:
静态int-bar();
};
模板
int Foo::bar(){return Foo::bar()+Foo::bar();}

局部专门化仅对类有效,对函数无效

解决方法:

template <typename U, typename V>
class Foo<std::pair<U, V> > { 
public:
 static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};
模板
类Foo{
公众:
静态int-bar(){return Foo::bar()+Foo::bar();}
};
如果您不想完全专门化类,请使用辅助结构

template<class T>
struct aux {
  static int bar();
};

template <>int aux <int>::bar() { return 4; }
template <>int aux <double>::bar() { return 8; }

template <typename U, typename V>
struct aux <std::pair<U, V> > { 
  static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};

template<class T>
class Foo : aux<T> {
  // ... 
};
模板
结构辅助{
静态int-bar();
};
模板int aux::bar(){return 4;}
模板int aux::bar(){return 8;}
模板
结构aux{
静态int-bar(){return Foo::bar()+Foo::bar();}
};
模板
类别Foo:aux{
// ... 
};

在本例中,所有的专门化都是类专门化。正确的。禁止使用函数partial specialize。只为功能条创建基类是可能的。@TimW,在这个问题中,关键是这个类不是专门化的。这超出了标准:“类模板的成员函数、成员类或静态数据成员可以显式专门化为隐式实例化的类专门化;如果此类类模板成员的显式专门化命名为隐式声明的特殊成员函数(第12条),该程序的格式不正确。”。它是该模板的一个给定隐式实例化(因此,没有模板参数依赖性)的专门化(不是任何部分专门化)。@litb因此,如果他没有编写专门化的类定义,他的程序是格式错误的。我只是假设他只是把它们排除在示例之外。很好的解释和解决方法。但是,解决方法是有限的,因为有时必须专门化现有类。例如,我必须专门化
boost::numeric::interval\u lib::checking\u base
的单个
static
函数,为此,我必须复制整个类,只需更改一点
boost::numeric::interval\u lib::checking\u base::empty\u lower()
。(顺便说一句,当
T
quantity
匹配时,我需要特别指出)@litb就我所知,他的所有函数都是类专门化的。我没有看到任何函数模板,是吗?@TimW:当你声明一个类模板时,每个成员函数都是一个独立的函数模板。OP试图专门化成员函数模板,而不专门化整个类模板。这就是重点。但是,函数模板不支持部分专门化。这就是问题所在。@TimW,没有函数模板。但也没有显式的类模板专门化。标准引用见上文:这是标准中的一个特例,允许显式专门化类模板的单独非模板成员,而不显式专门化其整个类模板。它通过命名一个给定的隐式实例化来工作(在他的例子中,例如
Foo
Foo
)在没有任何
Foo
的部分专门化的情况下,它将选择主模板并专门化其中的
bar
成员。但是,我只是假设他是懒惰的,并将类专门化的定义从示例注释中删除,返回t的大小不需要任何专门化:
static int Foo(){return sizeof(t);}
。我想知道这种模式是否对你真正的问题没有帮助。
template <typename U, typename V>
class Foo<std::pair<U, V> > { 
public:
 static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};
template<class T>
struct aux {
  static int bar();
};

template <>int aux <int>::bar() { return 4; }
template <>int aux <double>::bar() { return 8; }

template <typename U, typename V>
struct aux <std::pair<U, V> > { 
  static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};

template<class T>
class Foo : aux<T> {
  // ... 
};