模板运算符重载中的类型冲突
Type conflict in template operator overload
很抱歉,这听起来像是一个常见的问题,据我所知,我找不到问题的答案。最接近的帖子是这样的:只针对基本POD的的模板专业化
假设我有一个类template <class T> class A {...};
,我想重载运算符+作为内部二进制运算符(两个类型为a的对象)和混合二进制运算符(类型为a和数字POD类型的对象)。
理想情况下,我想写的是:
#include <type_traits>
using namespace std;
// Declare/fine template
template <class T> class A {...};
// Internal binary operator
template < class T, class U >
A< typename common_type<T,U>::type >
operator+ ( const A<T> &a, const A<U> &a ) { ... }
// Mixed binary operator
template < class T, class U >
A< typename common_type<T,U>::type >
operator+ ( const A<T> &a, const U &b ) { ... }
但第二个定义似乎与第一个定义相冲突。使用第二个定义,我知道如何确保U是数字POD类型,这不是重点。如果我这样做,问题是我无法知道U中包含的底层模板类型是什么
如果我的问题不够清楚,请告诉我,并提前感谢!:)
编辑:在我的最后一句话"U if it someA<T>
"中,模板规范被HTML过滤器删除了。简而言之,我是说T是隐藏的。
您可以使用一个小的辅助特性来区分A
的专业化和更通用的类型:
#include <type_traits>
// "A" template
template <typename> class A {};
// Traits for "A-ness":
template <typename> struct is_a : std::false_type { };
template <typename T> struct is_a<A<T>> : std::true_type { };
// Operators:
template <class T, class U>
A<typename std::common_type<T, U>::type>
operator+(const A<T> & a, const A<U> & b);
template <class T, class U,
typename = typename std::enable_if<!is_a<U>::value>::type>
A<typename std::common_type<T, U>::type>
operator+(const A<T> & a, const U & b);
这立即将第二过载从可行集合中排除,因此当只需要第一过载时,确定第二过载的返回类型的问题永远不会出现。
(这是在默认模板参数中使用enable_if
来控制过载集的示例。)
你可以写一个SFINAE友好的common_type
——我个人认为特质几乎总是SFINAE。也就是说:
// Black hole metafunction that eats everything
template<typename...> struct void_ { using type = void; };
template<typename... T>
using Void = typename void_<T...>::type;
// Due to std::common_type being variadic we need to
// pass a variadic pack around
template<typename... T> struct list {};
// Actually defined, but with no member types for SFINAE purposes
template<typename Sequence, typename Sfinae = void>
struct common_type_impl {};
template<typename... T>
struct common_type_impl<list<T...>, Void<typename std::common_type<T...>::type>>
: std::common_type<T...> {};
template<typename... T> struct common_type: common_type_impl<list<T...>> {};
现在,当A<T>
和U
之间没有通用类型时,过载将从候选列表中删除,而不是大声抱怨。
也可以完全替换std::common_type
,因为它计算的结果有自己的问题,如DR 2141中所述。我不会概述替代方案,因为不清楚什么是更好的解决方案,特别是我认为DR的拟议解决方案更糟。
相关文章:
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- C++哈希表 - 如何解决自定义数据类型作为键的unordered_map冲突?
- 模板冲突的类型-但类型应该是相同的cfr类层次结构
- 冲突声明/重新定义:不同的基本类型
- 可变参数的冲突类型
- 致命错误LNK1112:在 npm 安装期间,模块计算机类型'X86'与目标计算机类型'x64'冲突
- GCC 6.3.0 中的 ODR 冲突,类型在两个单独的翻译单元中定义
- 通过参考推断模板包中的冲突类型
- 错误:在 mingw64 上构建 cmake+boost 项目时'GetSystemTimeAsFileTime'的类型冲突
- 致命错误LNK1112:通过 vcvarsall .bat x86 运行构建'X86'模块计算机类型'x64'与目标计算机类型冲突
- 模板运算符重载中的类型冲突
- 相同定义变量的部分类型冲突
- g++4.7.1编译错误:“strsignal”的类型冲突
- 一元*的类型冲突error和无效类型参数具有int
- C++子类上的Bison类型冲突
- 数据类型冲突
- 防范非类型模板参数中的类型冲突
- 错误:指定的返回类型冲突,与通常不同
- 编译器报错类型冲突
- 错误:JNI方法的类型冲突