C++ 为什么在一种情况下使用私有内部类作为参数在头中是错误的,而在另一种情况下在调用函数中是错误的?
我试图建立一个模板化C++函数,它接受一个指向内部类对象的指针作为其参数。(我之前在这个问题上遇到的一个困难可以在“.”中看到)有一次我遇到了一个问题,后来证明是访问控制问题;我已经想出了如何避免这个问题,但我仍然有点不确定为什么这个问题会以这种方式被报道(这让我在追踪问题方面走上了一条花园道路) 基本上,我试图从C++ 为什么在一种情况下使用私有内部类作为参数在头中是错误的,而在另一种情况下在调用函数中是错误的?,c++,templates,inner-classes,private-members,C++,Templates,Inner Classes,Private Members,我试图建立一个模板化C++函数,它接受一个指向内部类对象的指针作为其参数。(我之前在这个问题上遇到的一个困难可以在“.”中看到)有一次我遇到了一个问题,后来证明是访问控制问题;我已经想出了如何避免这个问题,但我仍然有点不确定为什么这个问题会以这种方式被报道(这让我在追踪问题方面走上了一条花园道路) 基本上,我试图从friend类(因此具有所需的访问权限)中的方法调用函数,并使用私有内部类对象作为参数。当然,问题是非方法函数不是friend,因此无法访问内部类。但编译器将其报告为标头不匹配,而不是
friend
类(因此具有所需的访问权限)中的方法调用函数,并使用私有内部类对象作为参数。当然,问题是非方法函数不是friend
,因此无法访问内部类。但编译器将其报告为标头不匹配,而不是访问问题
首先是设置。我的数据类具有以下一般结构:
template <typename T>
class Outer
{
private:
struct Inner
{
T val;
Inner (T v) : val(v) { }
};
public:
Inner* ptr = nullptr;
friend class Other;
};
甚至不调用这个函数,只要定义了它,g++
就告诉我错误:'struct Outer::Inner'是私有的
,而clang++
告诉我错误:'Inner'是'Outer'的私有成员
。超级骗子
但是现在考虑这个模板函数,它从一个类中调用:
template <typename T>
void testFunction (const typename Outer<T>::Inner* p)
{
cout << p->val << endl;
}
struct Other {
template<typename T>
static void main(const Outer<T>& foo)
{
testFunction<T>(foo.ptr); //this line is flagged as the error
}
};
模板
void testFunction(const typename外部::内部*p)
{
CUTAVA< P >考虑此代码,这是完全合法的C++和:
#包括
模板
类外部
{
私人:
结构内部{};
};
模板
void testFunction(const typename外部::内部*p)
{
你的主要问题是:
为什么在一种情况下使用私有内部类作为参数在头中是错误的,而在另一种情况下在调用函数中是错误的
当编译器在Other::main
中处理以下行时
testFunction<T>(foo.ptr);
testFunction(foo.ptr);
它尝试创建testFunction
的实例。当时,它发现T::internal
是T
的私有类。问题仍然存在于testFunction
中。在第二种情况下,遇到问题时正在处理的行位于Other::main
中,因为可能存在错误对于Outer
的专门化,其Outer::Inner
实际上是格式良好的。您的testFunction
从未编译过,因此不会给您一个编译错误。Clang为您提供了正确的行为原因。两个编译器都忽略了您的testFunction
,因为它不是一个可行的选项,因为internal
是私有的,因此此时无法使用。模板仅在使用时才进行编译。此外,我不确定您使用的是哪个版本的g++,但我不确定您使用的是g++4.9。
#include <iostream>
template <typename T>
class Outer
{
private:
struct Inner { };
};
template <typename T>
void testFunction (const typename Outer<T>::Inner* p)
{
std::cout << "Hello!" << std::endl;
}
template<>
class Outer<double>{
public:
struct Inner { };
};
int main()
{
Outer<double>::Inner i;
testFunction<double>(&i);
return 0;
}
testFunction<T>(foo.ptr);