如何在涉及依赖作用域的内部类时C++查找模板化函数标头

How to make C++ find templated function header when dependent-scoped inner classes are involved?

本文关键字:查找 C++ 函数 内部类 依赖 作用域      更新时间:2023-10-16

我正在尝试构建一个模板化的C++函数,该函数接受指向内部类对象的指针作为其参数。 下面是所涉及的类结构的简化版本,类似于典型的链表或树类:

template <typename T>
struct Outer
{
  struct Inner
  {
    T val;
    Inner (T v) : val(v) { }
  };
  Inner* ptr;
  Outer(T val)
  {
    ptr = new Inner(val);
  }
};

我已经将它们设置为结构以排除任何访问控制问题,并删除了一些无关的实例变量。 考虑到这种类结构,这里有三个函数,其中前两个不是我想要的:

template <typename T>
void testOuter (const Outer<T>& obj)
{
  cout << obj.ptr->val << endl;
}
void testInnerInt (const Outer<int>::Inner* p)
{
  cout << p->val << endl;
}
template <typename T>
void testInnerTemplated (const typename Outer<T>::Inner* p)
{
  cout << p->val << endl;
}

第三个函数基本上是我想要的,标题方面(当然,它旨在作为更大代码体中的辅助函数(,但它不起作用。 如果我编译并运行以下主函数:

int main()
{
  Outer<int> foo(5);
  cout << foo.ptr->val << endl;
  testInnerInt(foo.ptr);
  //testInnerTemplated(foo.ptr);
  testOuter(foo);
}

它运行良好(打印5三次(,但是如果我取消注释该行并调用testInnerTemplated,我会收到一个编译器错误,说no matching function for call to ‘testInnerTemplated(Outer<int>::Inner*&)’(在 g++ 4.9.1 中(。 我想这是模板查找或匹配的问题,但是我如何告诉编译器如何解决它?

template <typename T>
void testInnerTemplated(const typename Outer<T>::Inner*);

编译器无法通过模板参数推导T,因为这是标准中定义的非推导上下文:

非推导上下文是:

使用限定 id 指定的类型的嵌套名称说明符。一种作为模板 ID 的类型,其中一个或多个模板参数是引用模板参数的表达式。

当以包含非推导上下文的方式指定类型名称时,构成该类型名称的所有类型也是非推导的。但是,复合类型可以包括推导类型和非推导类型。[示例:如果将类型指定为 A<T>::B<T2> ,则 TT2 都是不可推导的。同样,如果将类型指定为 A<I+J>::X<T>,则IJT 是不可推导的。如果指定一个类型为void f(typename A<T>::B, A<T>),则不推导A<T>::B中的T,但推导A<T>中的T。]

如果您希望从Inner中恢复Outer<>的类型信息,则可以使用特征。

template <typename T>
struct Outer
{
    typedef T TypeParam;
    struct Inner
    {
        typedef Outer<T> InnerOuter;
        T val;
        Inner (T v) : val(v) {}
    };
    Inner *ptr;
    Outer (T val) : ptr(new Inner(val)) {}
};

现在定义一个更通用的testInnerTemplated,但它使用特征来恢复传递给Outer<>的类型信息。

template <typename T>
void testInnerTemplated (const T * p)
{
  typename T::InnerOuter::TypeParam val = p->val;
  std::cout << val << std::endl;
}