如何确定类是否有特定的模板成员函数? [英] How to determine whether a class has a particular templated member function?
问题描述
我想知道是否可以扩展SFINAE方法来检测类是否具有某个成员函数(如下所述:
I was wondering if it's possible to extend the SFINAE approach to detecting whether a class has a certain member function (as discussed here:
是否有一个技术C ++知道一个类是否有给定签名的成员函数?
http://stackoverflow.com/questions/87372/is-there-a-technique-in-c-
"Is there a Technique in C++ to know if a class has a member function of a given signature?" http://stackoverflow.com/questions/87372/is-there-a-technique-in-c-to-know-if-a-class-has-a-member-function-of-a-given-s
),以支持模板化成员函数(to-template-a-class-has-a-member-function-of-a-given- ?例如。以便能够检测以下类中的函数foo:
) to support templated member functions? E.g. to be able to detect the function foo in the following class:
struct some_class {
template < int _n > void foo() { }
};
我认为这可能是为了foo的特定实例化,如果 void foo< 5>()
是成员):
I thought it might be possible to do this for a particular instantiation of foo, (e.g. check to see if void foo< 5 >()
is a member) as follows:
template < typename _class, int _n >
class foo_int_checker {
template < typename _t, void (_t::*)() >
struct sfinae { };
template < typename _t >
static big
test( sfinae< _t, &_t::foo< _n > > * );
template < typename _t >
static small
test( ... );
public:
enum { value = sizeof( test< _class >( 0 ) ) == sizeof( big ) };
};
然后执行 foo_int_checker< some_class,5> :: value
以检查 some_class
是否具有成员 void foo< 5>()
。然而,在MSVC ++ 2008上,这总是返回 false
,而g ++在 test(sfinae <_t,& _t :: foo& _n>>);
Then do foo_int_checker< some_class, 5 >::value
to check whether some_class
has the member void foo< 5 >()
. However on MSVC++ 2008 this always returns false
while g++ gives the following syntax errors at the line test( sfinae< _t, &_t::foo< _n > > );
test.cpp:24: error: missing `>' to terminate the template argument list
test.cpp:24: error: template argument 2 is invalid
test.cpp:24: error: expected unqualified-id before '<' token
test.cpp:24: error: expected `,' or `...' before '<' token
test.cpp:24: error: ISO C++ forbids declaration of `parameter' with no type
这两个都似乎失败,因为我试图从一个类型本身获取模板函数实例化的地址模板参数。有没有人知道这是可能的,还是因为某些原因而被标准禁止?
Both seem to fail because I'm trying to get the address of a template function instantiation from a type that is itself a template parameter. Does anyone know whether this is possible or if it's disallowed by the standard for some reason?
编辑:看起来我错过了 template
语法来使g ++正确地编译上面的代码。如果我改变的位,我得到的函数的地址为& _t :: template foo<然后程序编译,但我得到与MSVC ++相同的行为(
value
始终设置为 false
)
It seems that I missed out the ::template
syntax to get g++ to compile the above code correctly. If I change the bit where I get the address of the function to &_t::template foo< _n >
then the program compiles, but I get the same behaviour as MSVC++ (value
is always set to false
).
如果我注释掉 ...
c> test 强制编译器选择另一个,我在g ++中得到以下编译器错误:
If I comment out the ...
overload of test
to force the compiler to pick the other one, I get the following compiler error in g++:
test.cpp: In instantiation of `foo_int_checker<A, 5>':
test.cpp:40: instantiated from here
test.cpp:32: error: invalid use of undefined type `class foo_int_checker<A, 5>'
test.cpp:17: error: declaration of `class foo_int_checker<A, 5>'
test.cpp:32: error: enumerator value for `value' not integer constant
其中第32行是枚举{value = sizeof(test< _class>(0))== sizeof(big)};
线。不幸的是,这似乎并没有帮助我诊断问题:(。MSVC ++给出类似的不明确的错误:
where line 32 is the enum { value = sizeof( test< _class >( 0 ) ) == sizeof( big ) };
line. Unfortunately this doesn't seem to help me diagnose the problem :(. MSVC++ gives a similar nondescript error:
error C2770: invalid explicit template argument(s) for 'clarity::meta::big checker<_checked_type>::test(checker<_checked_type>::sfinae<_t,&_t::template foo<5>> *)'
在同一行。
如果我从一个特定的类而不是一个模板参数获取地址(即,而不是& _t :: template foo <_n>
我做& some_class :: template foo< _n>
)然后我得到正确的结果,但是我的检查器类被限制为检查单个类( some_class $此外,如果我执行以下操作:
What's strange is that if I get the address from a specific class and not a template parameter (i.e. rather than &_t::template foo< _n >
I do &some_class::template foo< _n >
) then I get the correct result, but then my checker class is limited to checking a single class (some_class
) for the function. Also, if I do the following:
template < typename _t, void (_t::*_f)() >
void
f0() { }
template < typename _t >
void
f1() {
f0< _t, &_t::template foo< 5 > >();
}
并调用 f1< some_class>()
然后我不会得到一个编译错误& _t :: template foo< 5>
。这表明问题只出现在当在SFINAE上下文中从本身是模板参数的类型获得模板成员函数的地址时。 Argon!
and call f1< some_class >()
then I DON'T get a compile error on &_t::template foo< 5 >
. This suggests that the problem only arises when getting the address of a templated member function from a type that is itself a template parameter while in a SFINAE context. Argh!
推荐答案
在Boost.MPL中已经实现了类似的东西,它被称为BOOST_MPL_HAS_XXX_TRAIT_DEF。请参阅:
There is something similar already implemented in Boost.MPL, it is called "BOOST_MPL_HAS_XXX_TRAIT_DEF". See:
http://www.boost.org/doc/libs/1_41_0/libs/mpl/doc/refmanual/has-xxx-trait-def.html
它可以检测类是否具有给定的类型。
It can detect if the class have a given named type.
对于你的具体情况,而不是传递函数指针作为参数(void(_t :: *)()),尝试使用它在你的方法的主体,即像:
Also, for your specific case, instead of passing the function pointer as a parameter (void (_t::*)()), try to use it in the body of your method, i.e., something like:
template < typename _t >
static big test( sfinae<_t> )
{
&_t::foo<_n>;
}
这篇关于如何确定类是否有特定的模板成员函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!