c++11 元编程:检查方法是否存在
c++11 metaprogramming: check for method existence
1) 我有两个 类 class A
和 class B
,它们都有一个名为 foo
的方法,但参数列表不同。
class A {
public:
void foo(int a);
};
class B {
public:
void foo(int a, int b);
};
2) 此外,我有一个带有模板参数 T
的 class C
,它还有一个 foo
方法,如下所示
template <typename T>
class C {
public:
void foo();
private:
T t_;
int a_;
int b_;
};
3) 我想同时使用 class A
和 class B
作为 class C
的模板参数。
说我想要一个方法 C::foo
来实现如下:
template <typename T>
void C<T>::foo()
{
if (compile time check: T has foo(int a, int b))
t_.foo(a_, b_);
else
t_.foo(a_);
}
如何在C++11
中表达上面的if
语句?
使用SFINAE(使用函数模板重载)。
template <typename T>
class C {
private:
T t_;
int a_;
int b_;
public:
template <typename X = T>
auto foo() -> decltype (std::declval<X>().foo(a_)) {
t_.foo(a_);
}
template <typename X = T>
auto foo() -> decltype (std::declval<X>().foo(a_, b_)) {
t_.foo(a_, b_);
}
};
如果您知道哪种类型包含 void foo(int a, int b);
,在这种情况下您知道,您可以使用模板专业化,例如
template <typename T>
class C
{
private:
T t_;
int a_;
int b_;
public:
// called for general use
void foo()
{
t_.foo(a_);
}
};
// specialized version for T = B
template<>
void C<B>::foo()
{
t_.foo(a_, b_);
}
1) 我有两个 类 class A
和 class B
,它们都有一个名为 foo
的方法,但参数列表不同。
class A {
public:
void foo(int a);
};
class B {
public:
void foo(int a, int b);
};
2) 此外,我有一个带有模板参数 T
的 class C
,它还有一个 foo
方法,如下所示
template <typename T>
class C {
public:
void foo();
private:
T t_;
int a_;
int b_;
};
3) 我想同时使用 class A
和 class B
作为 class C
的模板参数。
说我想要一个方法 C::foo
来实现如下:
template <typename T>
void C<T>::foo()
{
if (compile time check: T has foo(int a, int b))
t_.foo(a_, b_);
else
t_.foo(a_);
}
如何在C++11
中表达上面的if
语句?
使用SFINAE(使用函数模板重载)。
template <typename T>
class C {
private:
T t_;
int a_;
int b_;
public:
template <typename X = T>
auto foo() -> decltype (std::declval<X>().foo(a_)) {
t_.foo(a_);
}
template <typename X = T>
auto foo() -> decltype (std::declval<X>().foo(a_, b_)) {
t_.foo(a_, b_);
}
};
如果您知道哪种类型包含 void foo(int a, int b);
,在这种情况下您知道,您可以使用模板专业化,例如
template <typename T>
class C
{
private:
T t_;
int a_;
int b_;
public:
// called for general use
void foo()
{
t_.foo(a_);
}
};
// specialized version for T = B
template<>
void C<B>::foo()
{
t_.foo(a_, b_);
}