C++ 模板运算符 + 内部类中的重载
C++ template operator+ overloading in inner class
如何为类模板的内部类重载运算符+?我已经搜索了几个小时,但找不到答案。这是一个不起作用的最小示例:
#include <iostream>
using namespace std;
template <class T>
struct A
{
struct B
{
T m_t;
B(T t) : m_t(t) {}
};
};
template <class T>
typename A<T>::B operator+(typename A<T>::B lhs, int n)
{
lhs.m_t += n;
return lhs;
}
int main(int argc, char **argv)
{
A<float> a;
A<float>::B b(17.2);
auto c = b + 5;
cout << c.m_t << endl;
return 0;
}
如果我这样编译,我会得到error: no match for ‘operator+’ (operand types are ‘A<float>::B’ and ‘int’)
我在某处找到了应该声明operator+(A<T>::B, int)
的地方,所以如果我添加以下内容:
struct B;
friend B operator+(typename A<T>::B lhs, int n);
struct A {
后,我收到链接器错误。
如果我不尝试调用 b+5,程序可以正确编译。
他们(STL制造商)是如何用int编程vector<T>::iterator operator+
的?我在任何地方都找不到它(而且很难阅读 stl_vector.h)!
谢谢。
您面临的问题是,当您声明如下函数模板时:
template <class T>
typename A<T>::B operator+(typename A<T>::B lhs, int n)
typename A<T>::B lhs
是一个非推导的上下文。编译器无法确定该上下文中的T
是什么,因此它不会尝试,因此无法找到您的operator+
。考虑一个简化的示例,例如:
template <class T> void foo(typename T::type );
struct A { using type = int; };
struct B { using type = int; };
foo(0); // what would T be?
// how many other possible T's are there that fit?
为了使模板推导在非推导上下文中成功,必须显式指定模板类型参数。在这种情况下,语法的怪物编译:
auto c = ::operator+<float>(b, 5);
但可能不是您的预期用途!
<小时 />您需要在struct B
内声明operator+
:
struct B
{
T m_t;
B(T t) : m_t(t) {}
// member
B operator+(int n) {
return B(m_t + n);
}
// or non-member, non-template friend
friend B operator+(B lhs, int n) {
lhs.m_t += n;
return lhs;
}
};
也许你可以做这样的事情:
#include <iostream>
#include <type_traits>
using namespace std;
template <class T>
struct A
{
struct B
{
typedef A<T> OuterType;
T m_t;
B(T t) : m_t(t) {}
};
};
template <class T>
typename T::OuterType::B operator+(T lhs, int n)
{
lhs.m_t += n;
return lhs;
}
int main(int argc, char **argv)
{
A<float> a;
A<float>::B b(17.2);
auto c = b + 5;
cout << c.m_t << endl;
return 0;
}
编辑:这将起作用,因为T可以从表达式(b + 5)
的第一个操作数中推导,并且仅适用于包含OuterType
定义的结构的结构,该结构将子类型B作为内部结构。您可以使用 typename enable_if<is_same<T, typename T::OuterType::B>::value, T>::type
而不是结果类型来测试此结构是否与 T 相同:typename T::OuterType::B
- 在设计 SDK 时,我是否应该在 C++ 头文件中完全隐藏内部类?
- 如何声明由多个线程调用的 C++ DLL 的内部类,而无需导出类
- 从内部类继承
- 如何将枚举类转发声明为模板化类的内部类?
- 从内部类中的方法从包含类调用方法
- 从模板化父类中的派生内部类访问受保护的成员变量
- C++模板类的内部类访问
- 使用类模板的内部类模板专用化模板
- 如何使用包含内部类的类实例有效地从内部类访问成员?
- C++ 如何在外部类中声明的内部类中使用变量
- 在C++中将内部类实现为具有名称空间的独立类有什么好处
- 参数化类的别名(或类型定义)内部类
- 从内部类的析构函数调用虚拟函数
- 如何在没有setter的情况下设置类内部类的成员变量?
- 函数重载:内置类型与用户定义类型
- C++模板内部类友元运算符重载
- 如果内部类具有与外部类同名的函数,那么它是否在 C++ 和 Java 中隐藏了覆盖或重载
- C++ 模板运算符 + 内部类中的重载
- 内部类的不可见运算符<<重载
- 内部类模板的非成员运算符重载