当前位置: 首页 > 知识库问答 >
问题:

C++:在模板类的模板类型中存在命名成员时提供类函数?

孙京
2023-03-14

我试图做到以下几点:一个模板化的类应该提供一些函数,这些函数取决于它模板化的类型是否包含一个具有给定名称的成员变量。作为示例,下面的伪代码应该只在模板化的结构/类具有名为“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 { };

感谢任何帮助。

共有1个答案

潘俊
2023-03-14

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

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本身--它只是“碰巧”使用它作为默认参数。那是关键部分。

 类似资料:
  • 我有一个模板化的C++类,它也有一个模板化的成员函数。这个成员函数的模板参数以特定的方式依赖于类的模板参数(请参阅下面的代码)。我正在为其模板参数的两个不同值实例化(而不是专门化)该类。一切都在这一点上进行。但是,如果我调用模板化的成员函数,对第一个实例化对象的调用只会编译,而不会编译第二个。似乎编译器没有为模板类的第二次实例化实例化模板化成员函数。我正在使用“g++filename.cpp”编译

  • 我有一个问题,我想在下面的代码中专门化模板类的模板成员函数。这个问题的答案是模板类成员函数的显式特化,这似乎表明它无法完成。这是正确的吗,如果是这样,我可以使用任何解决方法,以便在编译时通过内联inc函数进行扩展? 非常感谢! g吐槽道: test2.cpp:32:13: 错误: 非命名空间作用域中的显式专用化 'struct IdxIterator' test2.cpp:32:25: 错误: 非

  • 是否可以编写一个模板,根据是否在类上定义了某个成员函数来改变行为? 下面是我想写的一个简单的例子: 因此,如果定义了,那么它将使用它;否则就不会。我不知道怎么做的神奇部分是“function_exists”部分。

  • 是否有人知道此显式特化是否有效: clang 主干 (12/3/2013) 给出以下错误: f:...\test.cpp:36:20: 错误: 从类 'O' 中出线定义 “Fun” 没有定义 1生成错误。 任何来自标准的支持参考来证明你的答案将不胜感激! 注意:我有点惊讶这是一个错误——我认为应该为任何以< code >开始实例化“Fun”的模板参数族选择专门化 这是一个叮当的错误还是我期望中的错

  • 我是新使用模板。作为标题,我有一个非模板类(Obj和ObjBase)和一个模板类pitem。我想让pItem::RefValue()访问obj中的私有成员。 我想下面的行得通: 它不: 错误C2248:“obj::GetValue”:无法访问类“obj”中声明的私有成员 注意:请参阅对正在编译的函数模板实例化“int PItem::GetValue(void)”的引用 编译器投诉:

  • 假设我们有一个类,如下所示: 因此,在这里,我需要以某种方式存储容器的类型(或)。我知道在我的程序的这一点,它是完全确定的。我需要存储它,因为稍后我可能不得不将我的强制转换回或,例如在另一个函数中: 我考虑过使用包含所有不同受支持类型的值的并将该类型保存在该枚举类型的附加成员变量中。然后,我必须使用语句来检查所有不同的可能性并执行正确的强制转换。但是,我想是不是没有更简单的方法。 我主要想做的是存