C++:在其模板化类型中存在命名成员时,在模板化类中提供一个类函数

C++: providing a class function in templated class on existence of named member in its templated type?

本文关键字:类函数 一个 类型 存在 成员 C++      更新时间:2023-10-16

我正在尝试执行以下操作:模板化类应提供一些函数,具体取决于模板化的类型是否包含具有给定名称的成员变量。例如,以下伪代码仅在模板化结构/类具有名为"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,特征,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 { };

任何帮助表示赞赏。

是的,这是可能的。下面是一个示例:

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本身强制执行任何内容——它只是"碰巧"将其用作默认参数。这是关键部分。