如何解决不使用decltype复制相同行为
以下代码可用于快速调试。它可以打印来自STL的矢量之类的漂亮容器,同时还可以使用SFINAE技术为基本类型和可流类型提供打印性属性。
我想在不使用decltype
的情况下复制相同的行为。对于我想到的一些项目,复制此行为的任何其他整洁技术都将在实现方面非常有用。当前线程也可以被视为this线程的延续(也是我的意思)。我设法在C ++ 20(GCC 10.2.0)中使用concepts
获得了一个整洁的工作实现,而没有使用decltype
,但是我希望能够在C ++ 17中实现( GCC 9.2.0)及更低版本(显然,没有概念,如前所述)。
namespace debugging {
template <typename T>
class range {
public:
T begin,end;
};
template <typename T>
auto make_range (const T& b,const T& e) -> range <T> {
return {b,e};
}
template <typename T>
auto is_streamable_object (T *x) -> decltype(std::cerr << *x,std::true_type());
template <typename T>
auto is_streamable_object (...) -> decltype(std::false_type());
class view {
private:
std::ostream& stream;
public:
view (std::ostream& os = std::cerr) : stream (os)
{ };
~view ()
{ stream << std::endl; };
#ifdef LOST_IN_SPACE
template <typename T>
std::enable_if_t <std::is_same <decltype(is_streamable_object <T> (nullptr)),std::true_type>::value,view&>
operator << (const T& t) {
stream << std::boolalpha << t; return *this;
}
template <typename T>
std::enable_if_t <std::is_same <decltype(is_streamable_object <T> (nullptr)),std::false_type>::value,view&>
operator << (const T& t) {
return *this << make_range(begin(t),end(t));
}
template <typename T>
view& operator << (const range <T>& r) {
stream << "[";
for (auto i = r.begin,j = i; i != r.end; ++i)
*this << *i << (++j == r.end ? "]" : ",");
return *this;
}
template <typename A,typename B>
view& operator << (const std::pair <A,B>& p) {
stream << '(' << p.first << "," << p.second << ')';
return *this;
}
#else
template <typename T> view& operator << (const T&)
{ return *this; }
#endif
};
} // namespace debugging
测试代码,以防您想自己快速尝试一下:
#define print(x) " [" << #x << ": " << x << "] "
using view = debugging::view;
view debug (std::cerr);
auto test () -> void {
std::vector <int> v {1,2,3,4,5};
std::map <int,int> m {{1,2},{3,4}};
debug << print(v) print(m) << "\nHello World";
}
解决方法
当然,这是使用sizeof
的实现:
template<class T,class = std::false_type>
struct is_streamable_object : std::false_type {};
template<class T>
struct is_streamable_object<T,std::bool_constant<sizeof(std::cerr << std::declval<T>()) == 0>> : std::true_type {};
您可以使用的其他关键字包括alignof
,noexcept
,typeid
和explicit
(C ++ 20之后的最后一个关键字)。
基本上,您想执行表达式SFINAE,这需要构造一个不求值的表达式。 operators that allow constructing unevaluated expressions是上面提到的那些,加上decltype
(您不想使用)和requires
(C ++ 20)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。