枚举和静态const成员变量在模板特征类中的用法
enum and static const member variable usage in template trait class
我想通过查看是否提供了operator<<
的过载来测试类是否可以流到ostream&
。根据这些帖子,我尝试使用C 11编写另一个版本。这是我的尝试:
#include <iostream>
#include <type_traits>
namespace TEST{
class NotDefined{};
template<typename T>
NotDefined& operator << (::std::ostream&, const T&);
template <typename T>
struct StreamInsertionExists {
static std::ostream &s;
static T const &t;
enum { value = std::is_same<decltype(s << t), NotDefined>() };
};
}
struct A{
int val;
friend ::std::ostream& operator<<(::std::ostream&, const A&);
};
::std::ostream& operator<<(::std::ostream& os, const A& a)
{
os << a.val;
return os;
}
struct B{};
int main() {
std::cout << TEST::StreamInsertionExists<A>::value << std::endl;
std::cout << TEST::StreamInsertionExists<B>::value << std::endl;
}
但这无法编译:
test_oper.cpp:40:57: error: reference to overloaded function could not be resolved; did you mean to call it? std::cout << TEST::StreamInsertionExists<A>::value << std::endl; /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ostream:1020:1: note: possible target for call endl(basic_ostream<_CharT, _Traits>& __os) test_oper.cpp:30:17: note: candidate function not viable: no known conversion from 'TEST::NotDefined' to '::std::ostream &' (aka 'basic_ostream<char> &') for 1st argument ::std::ostream& operator<<(::std::ostream& os, const A& a) test_oper.cpp:15:15: note: candidate template ignored: couldn't infer template argument 'T' NotDefined& operator << (::std::ostream&, const T&);
但是,如果我更换了线
enum { value = std::is_same<decltype(s << t), NotDefined>() };
与
static const bool value = std::is_same<decltype(s << t), NotDefined>();
然后一切都编译了。
为什么enum
和bool
?
value
是 StreamInsertionExists<T>
中匿名名称的枚举。当您尝试这样做时:
std::cout << StreamInsertionExists<T>::value;
编译器在operator<<(std::ostream&, StreamInsertionExists<T>::E)
上进行过载查找。在典型情况下,它会在enum
上进行积分促销,并将其作为int
流式传输。但是,您还定义了此操作员:
template<typename T>
NotDefined& operator << (std::ostream&, const T&);
比int
版本更好地匹配CC_13版本(确切的匹配与积分促销),因此优先。是的,这是一个函数模板,但是仅当转换序列匹配时,非修正才是首选 - 在这种情况下,它们不符合。
因此,这线:
std::cout << TEST::StreamInsertionExists<A>::value << std::endl;
是:
operator<<(operator<<(std::cout, TEST::StreamInsertionExists<A>::value), std::endl);
和最内部的operator<<
调用将使用您的NotDefined&
模板。因此,下一步将是找到适当的功能呼叫:
operator<<(NotDefined&, std::endl);
,operator<<
没有这样的过载,因此错误。
如果将value
更改为bool
,则没有这样的问题,因为是 operator<<
完全将bool
摄取:#6。也就是说,即使使用bool
,您的特征仍然不正确,因为它总是返回false
。您的NotDefined
版本实际上返回参考,因此您必须对此进行检查。而且, NotDefined&
表示不是定义的,因此您必须翻转符号:
static const bool value = !std::is_same<decltype(s << t), NotDefined&>();
但是,这特别容易出错。现在,cout << B{};
而不是未能编译会给您带来链接错误,并且cout << B{} << endl;
给您带来相同的混淆过载错误,涉及endl
,而不是简单地统计您无法流式传输B
。
您应该只想做:
template <typename...>
using void_t = void;
template <typename T, typename = void>
struct stream_insertion_exists : std::false_type { };
template <typename T>
struct stream_insertion_exists<T, void_t<
decltype(std::declval<std::ostream&>() << std::declval<T>())
> > : std::true_type { };
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 这个指针在c++中的用法
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 特征命名访问向量段
- 将特征矩阵的向量设置为0
- 特征:模板函数中矩阵的平面图
- basic_string的前导/尾部不区分空格的特征
- 特征 3 类的模板专用化
- 当C++中需要自动删除时,这是静态的正确用法吗?
- 特征 c++:复矩阵的面积双曲正切(atanh)
- libstdc++ 文件系统中未初始化的用法?
- C++ 中的特征向量计算
- 根据C++标准的定义实现"is_similar"类型特征
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- 复制和交换习惯用法与移动操作之间的交互
- 有没有办法找到特征矩阵系数的中值?
- 如何将高维数据映射到特征类型?
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 枚举和静态const成员变量在模板特征类中的用法