关于c ++:c ++ 11元编程:检查方法是否存在

c++11 metaprogramming: check for method existence

本问题已经有最佳答案,请猛点这里访问。

1)我有两个类class Aclass B,它们都有一个方法,叫做foo,但是参数列表不同。

1
2
3
4
5
6
7
8
9
class A {
public:
  void foo(int a);
};

class B {
public:
  void foo(int a, int b);
};

2)另外,我还有一个带模板参数Tclass C,还有一个foo方法,如下所示

1
2
3
4
5
6
7
8
9
template <typename T>
class C {
public:
  void foo();
private:
  T t_;
  int a_;
  int b_;
};

3)我想使用class Aclass B作为class C的模板参数。我希望实现一个方法C::foo,如下所示:

1
2
3
4
5
6
7
8
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(函数模板重载)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);,在这种情况下,您可以使用模板专门化,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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::foo()
{
    t_.foo(a_, b_);
}