1

我正在尝试执行以下操作:模板化类应该提供一些函数,这取决于它被模板化的类型是否包含具有给定名称的成员变量。例如,以下伪代码仅在模板结构/类具有名为“id”的成员时才应提供“printid()”:

#include <iostream>
#include <type_traits>

struct A { int id; };
struct B { };

template<typename T>
class foo
{
  T myvar;

public:
  #if exists T.id   (or the alternative: #if exists myvar.id)
  printid() { std::cout << "I have element id."; }
  #endif
};

int main(){
  foo<A> ok;
  ok.printid();   // should compile and execute

  foo<B> nok;
  nok.printid();  // should not compile
  return 0;
}

围绕 SFINAE、traits、std::enable_if 和 StackOverflow 进行挖掘,我认为它可以以某种方式完成。但是我不知何故未能将 enable_if 与问题如何检测类中是否存在特定成员变量?

template<typename T, typename = void>
struct has_id : std::false_type { };

template<typename T>
struct has_id<T, decltype(std::declval<T>().id, void())> : std::true_type { };

任何帮助表示赞赏。

4

1 回答 1

3

是的,有可能。这是一个例子:

template<typename T>
class foo
{
  T myvar;

public:
  template <class _T = T,
            class = typename std::enable_if<
                      !std::is_function<decltype(_T::id)>::value>
                    ::type>
  void printid() { std::cout << "I have element id."; }
};

具体来说,请注意我们如何“接受” T_T以便不对类模板参数施加约束(这会使类本身不可编译)。相反,我们正在创建一个新的、独立的模板成员函数,它不会强加任何东西T——它只是“碰巧”将其用作默认参数。这是关键部分。

于 2016-01-27T19:35:08.623 回答