模板参数匹配 [英] Template argument matching
问题描述
请查看以下代码:
模板< typename T,typename Enable = void>
级A
{
public:
enum {value = 0};
};
模板< typename T>
A类< T,typename T ::启用>
{
公开:
enum {value = 1};
};
B级
{
public:
typedef void Enable;
};
class C >
{
};
int main(int argc,char * argv [])
{
int b = A< B> :: value; //应为1
int c = A< C> :: value; //应该是0
返回0;
}
这里的目标是创建一个名为A的类模板如果T :: Enable存在,那么
A< T> :: value是1的方式,否则为0。我已经在MSVC ++ 7.1上尝试了这个
,它确实有效,但只有当T :: Enable与
完全相同时,才能使用与默认值相同的类型模板参数
A.例如,如果我将B中的typedef更改为
typedef int Enable; // int而不是void
那么main中变量b的值将为0.
我想知道为什么'那个' 。我认为专业化将是
更好地匹配T :: Enable存在的所有类型,无论它实际上是什么类型的b $ b类型。而且我无法真正看到与
第二个模板参数的关联。
Imre
Imre写道:请看下面的代码:
template< ; typename T,typename Enable = void>
A级
{
公开:
enum {value = 0};
};
> template< typename T>
A类< T,typename T :: Enable>
{
公开:
enum {value = 1};
};
B班
{
公开:
typedef void启用;
};
C类
{
};
int main(int argc,char * argv [])
{
int b = A< B> :: value; //应该是1
int c = A< C> :: value; //应该是0
返回0;
}
这里的目标是以一种方式创建一个名为A的类模板
A< T> ::如果T :: Enable存在,则值为1,否则为0。我在MSVC ++ 7.1上尝试了
,它确实有效,但只有当T :: Enable是
与
A的启用模板参数的默认值完全相同时例如,如果我将B中的typedef更改为
typedef int Enable; // int而不是void
那么main中变量b的值将为0.
我想知道为什么'那样。我认为专门化将
更好地匹配T :: Enable存在的所有类型,无论
它实际意味着什么类型。而且我无法真正看到与
连接的第二个模板参数。
Imre
我在猜你真正想要的是一个特质:
.. #include< iostream>
..
。 。template< typename T>
.. class Trait
.. {
.. public:
..枚举{ENABLE = 0};
..};
这定义了一个特征,默认情况下为零。现在你可以定义你的
''''这样的类:
.. template< typename T,typename T2 = Trait< T> >
.. A级
.. {
.. public:
.. enum {value = T2 :: ENABLE};
..};
从Trait类中的''ENABLE''枚举中获取''value'' (默认情况下,这是
零)。现在你可以创建你的其他课程:
.. class B {};
.. class C {};
现在,专门化Trait< T>所以''ENABLE''设置为一个'B'类':
..模板<>
..类Trait< ; B>
.. {
.. public:
.. enum {ENABLE = 1};
..};
这意味着''B''现在可以用于'A'中你想做的任何事情。
.. int main(int argc,char * argv [])
.. {
.. int b = A< B> :: value; //应该是1
.. int c = A< C> :: value; //应该是0
..
.. std :: cout<< b<< " " << c<< std :: endl;
..
..返回0;
..}
这应该打印out1 0 (正如预期的那样)。
希望这会有所帮助,
-shez-
我认为您可能会将默认模板
参数与部分模板专业化混淆。
如果您查看上面的代码,两者都不是lines:
int b = A< B> :: value; //应该是1
int c = A< C> :: value; //应为0
明确提供原始模板的启用参数。
出于这个原因,你有隐含的书面形式:
int b = A< B,void> :: value;
int c = A< C,void> :: value;
类型为void。
当编译器决定是否使用
部分模板专门化时:
模板< typename T>
A类< T,typename T ::启用>
{
公开:
枚举{value = 1};
};
T :: Enable必须是void类型才能选择专门的
。
如果你写:
B级
{
public:
typedef int Enable;
};
然后是隐式写的行:
int b = A< B,void>: :value;
不使用部分模板专业化:
模板< typename T>
A类< T,typename T ::启用>
{
公开:
枚举{value = 1};
};
因为T ::启用(真正的B ::启用)是int类型,第二个
参数是A< B,void>属于void类型。换句话说,由于void是第二个模板参数的类型,因此无法应用类型为int
的T :: Enable,并且无法选择特化,因为
类型冲突。
我希望这有帮助! =)
Michael Loritsch
Shezan Baig写道:这定义了一个特征,默认情况下为零。现在你可以像这样定义你的'A'类了:
。 template< typename T,typename T2 = Trait< T> >
。 A级
。 {
。公众:
。枚举{value = T2 :: ENABLE};
。 };
另外,如果你想为ENABLE = 1设置一个单独的专业化(在原帖中为
),你可以这样做:
..模板< typename T,
.. typename T2 = Trait< T>,
。 .int ENABLE = T2 :: ENABLE>
.. A级
.. {
.. public:
.. enum {value = 0};
..};
..
.. template< typename T, typename T2>
.. A类< T,T2,1>
.. {
.. public:
.. enum {value = 1};
..};
这将为您提供编译时多态性我认为您
在您的原始帖子中寻找。
希望这会有所帮助,
-shez-
Please take a look at the following code:
template <typename T, typename Enable = void>
class A
{
public:
enum { value = 0 };
};
template <typename T>
class A<T, typename T::Enable>
{
public:
enum { value = 1 };
};
class B
{
public:
typedef void Enable;
};
class C
{
};
int main(int argc, char *argv[])
{
int b = A<B>::value; // should be 1
int c = A<C>::value; // should be 0
return 0;
}
The goal here was to create a class template called A in a way that
A<T>::value is 1 if T::Enable exists, and 0 otherwise. I''ve tried this
on MSVC++ 7.1, and it actually works, but only if T::Enable is exactly
the same type as the default value of the Enable template argument of
A. For example, if I change the typedef in B to
typedef int Enable; // int instead of void
then the value of variable b in main will be 0.
I''d like to know why''s that. I thought that the specialization would be
a better match for all types where T::Enable exists, regardless of what
type it actually means. And I can''t really see the connection with the
second template argument.
Imre
Imre wrote:Please take a look at the following code:
template <typename T, typename Enable = void>
class A
{
public:
enum { value = 0 };
};
template <typename T>
class A<T, typename T::Enable>
{
public:
enum { value = 1 };
};
class B
{
public:
typedef void Enable;
};
class C
{
};
int main(int argc, char *argv[])
{
int b = A<B>::value; // should be 1
int c = A<C>::value; // should be 0
return 0;
}
The goal here was to create a class template called A in a way that
A<T>::value is 1 if T::Enable exists, and 0 otherwise. I''ve tried this on MSVC++ 7.1, and it actually works, but only if T::Enable is exactly the same type as the default value of the Enable template argument of
A. For example, if I change the typedef in B to
typedef int Enable; // int instead of void
then the value of variable b in main will be 0.
I''d like to know why''s that. I thought that the specialization would be a better match for all types where T::Enable exists, regardless of what type it actually means. And I can''t really see the connection with the second template argument.
Imre
I''m guessing what you really want is a "trait":
.. #include <iostream>
..
.. template <typename T>
.. class Trait
.. {
.. public:
.. enum { ENABLE = 0 };
.. };
This defines a trait, by default it is zero. Now you can define your
''A'' class like this:
.. template <typename T, typename T2 = Trait<T> >
.. class A
.. {
.. public:
.. enum { value = T2::ENABLE };
.. };
This gets ''value'' from the ''ENABLE'' enum in your Trait class (which is
zero by default). Now you can create your other classes:
.. class B { };
.. class C { };
Now, specialise Trait<T> so that ''ENABLE'' is set to one for class ''B'':
.. template <>
.. class Trait<B>
.. {
.. public:
.. enum { ENABLE = 1 };
.. };
This means that ''B'' is now enabled for whatever you want to do in ''A''.
.. int main(int argc, char *argv[])
.. {
.. int b = A<B>::value; // should be 1
.. int c = A<C>::value; // should be 0
..
.. std::cout << b << " " << c << std::endl;
..
.. return 0;
.. }
This should print out "1 0" (as expected).
Hope this helps,
-shez-
I think it is possible that you are confusing default template
parameters with with partial template specialization.
If you look at your code above, neither of the lines:
int b = A<B>::value; // should be 1
int c = A<C>::value; // should be 0
explicitly supplies the ''Enable'' parameter of your original template.
For that reason, you have implicitly written:
int b = A<B, void>::value;
int c = A<C, void>::value;
In other words, in both cases, your second template parameter is of
type void.
This means that when the compiler is deciding whether or not to use the
partial template specialization:
template <typename T>
class A<T, typename T::Enable>
{
public:
enum { value = 1 };
};
that T::Enable must be of type void in order to the specialization to
be chosen.
If you write:
class B
{
public:
typedef int Enable;
};
then the implicitly written line:
int b = A<B, void>::value;
does not use the partial template specialization:
template <typename T>
class A<T, typename T::Enable>
{
public:
enum { value = 1 };
};
because T::Enable (really B::Enable) is of type int, and the second
parameter of A<B, void> is of type void. In other words, since void is
the type of the second template parameter, a T::Enable of type int
cannot be applied, and the specialization cannot be chosen because of
the type conflict.
I hope this helps! =)
Michael Loritsch
Shezan Baig wrote:This defines a trait, by default it is zero. Now you can define your
''A'' class like this:
. template <typename T, typename T2 = Trait<T> >
. class A
. {
. public:
. enum { value = T2::ENABLE };
. };
Also, if you want to have a separate specialisation for ENABLE = 1 (as
in your original post), you can do this:
.. template <typename T,
.. typename T2 = Trait<T>,
.. int ENABLE = T2::ENABLE >
.. class A
.. {
.. public:
.. enum { value = 0 };
.. };
..
.. template <typename T, typename T2>
.. class A<T, T2, 1>
.. {
.. public:
.. enum { value = 1 };
.. };
This will give you the compile-time polymorphism I think you were
looking for in your original post.
Hope this helps,
-shez-
这篇关于模板参数匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!