我正在尝试为operator!=
实现一个重载,它会比较两个不同类型的对象(InnerA
和InnerB
)。这两种类型都定义为模板类(Outer
)中的嵌套类。重载需要是两个类的朋友,因为它访问每个类的私有字段。
template<typename Type> class Outer
{
public:
class InnerA;
class InnerB;
};
template<typename Type> bool operator!=(const typename Outer<Type>::InnerA& lhs, const typename Outer<Type>::InnerB& rhs);
template<typename Type> class Outer<Type>::InnerA
{
const int val = 0;
friend bool operator!=<>(const InnerA& lhs, const typename Outer<Type>::InnerB& rhs);
};
template<typename Type> class Outer<Type>::InnerB
{
const int val = 1;
friend bool operator!=<>(const typename Outer<Type>::InnerA& lhs, const InnerB& rhs);
};
template<typename Type> bool operator!=(const typename Outer<Type>::InnerA& lhs, const typename Outer<Type>::InnerB& rhs)
{
return lhs.val != rhs.val;
}
int main()
{
bool b = Outer<int>::InnerA() != Outer<int>::InnerB();
}
以上代码无法编译,发出:
In instantiation of 'class Outer<int>::InnerA':
34:33: required from here
15:17: error: template-id 'operator!=<>' for 'bool operator!=(const Outer<int>::InnerA&, const Outer<int>::InnerB&)' does not match any template declaration
In instantiation of 'class Outer<int>::InnerB':
34:57: required from here
22:17: error: template-id 'operator!=<>' for 'bool operator!=(const Outer<int>::InnerA&, const Outer<int>::InnerB&)' does not match any template declaration
In function 'int main()':
34:35: error: no match for 'operator!=' (operand types are 'Outer<int>::InnerA' and 'Outer<int>::InnerB')
34:35: note: candidate is:
26:30: note: template<class Type> bool operator!=(const typename Outer<Type>::InnerA&, const typename Outer<Type>::InnerB&)
26:30: note: template argument deduction/substitution failed:
34:57: note: couldn't deduce template parameter 'Type'
虽然可能有更好的方法来实现类似的结果,但我很好奇我的代码究竟出了什么问题。谢谢!
答案 0 :(得分:1)
template<typename Type> class Outer<Type>::InnerA
{
friend bool operator!=(const InnerA& lhs, const typename Outer<Type>::InnerB& rhs) { return true; }
};
template<typename Type> class Outer<Type>::InnerB
{
friend bool operator!=(const typename Outer<Type>::InnerA& lhs, const InnerB& rhs) { return true; }
};
这些是非模板的朋友。他们也发生冲突。所以实现其中一个,省略另一个。
他们将通过ADL找到。
答案 1 :(得分:1)
我找到了以下解决方法,将重载重构为其中一个嵌套类的方法:
template<typename Type> class Outer
{
public:
class InnerA;
class InnerB;
};
template<typename Type> class Outer<Type>::InnerA
{
const int val = 0;
public:
bool operator!=(const typename Outer<Type>::InnerB& other);
};
template<typename Type> class Outer<Type>::InnerB
{
const int val = 1;
friend bool Outer<Type>::InnerA::operator!=(const InnerB& other);
};
template<typename Type> bool Outer<Type>::InnerA::operator!=(const typename Outer<Type>::InnerB& other)
{
return val != other.val;
}
int main()
{
bool b = Outer<void>::InnerA() != Outer<void>::InnerB();
}
但是,我仍然很好奇是否可以使用非成员朋友功能完成同样的问题。
答案 2 :(得分:0)
问题中的代码问题最终导致不会尝试嵌套在依赖类型中的类型名称(例如Outer<Type>::Inner
)。
这个问题基本上是Nested template and parameter deducing的副本。可以找到有关这是一个问题的原因的详细说明here。