在下面的代码中,断言没有失败,那么除了type_supports_deref_t<T>{})
之外true_type
如何构建其他任何内容?
#include <iostream>
#include <memory>
#include <type_traits>
#include <utility>
#include <typeinfo>
template <typename T>
struct ptr_traits {
using supports_deref = std::false_type;
};
template <typename T>
struct ptr_traits<T*> {
using supports_deref = std::true_type;
};
template <typename T>
struct ptr_traits<std::unique_ptr<T>> {
using supports_deref = std::true_type;
};
template <typename T>
struct ptr_traits<std::shared_ptr<T>> {
using supports_deref = std::true_type;
};
template <typename T>
using type_supports_deref_t = typename ptr_traits<typename std::remove_cv<T>::type>::supports_deref;
template <typename T>
T& foo_impl(T&& t, std::false_type){
std::cout<<"No-ptr .. \n";
return t;
}
template <typename T>
T& foo_impl(T&& t, std::true_type){
std::cout<<"Ptr .. \n";
return *t;
}
template <typename T>
T& foo(T&& t){
return foo_impl(t, type_supports_deref_t<T>{});
}
struct Bar {
int value = 10;
};
int main(){
Bar* b1 = new Bar();
foo(b1); // calls no ptr...
std::cout<<std::boolalpha;
std::cout<<(type_supports_deref_t<Bar*>::value); // returns true
static_assert(std::is_same<std::true_type, decltype(type_supports_deref_t<Bar*>{})>::value, ""); // passes
return 0;
}
有输出:
No-ptr ..
true
在我看来,只有在调用false_type
重载时才有意义,但断言没有失败,那么发生了什么?
编辑:这是一个可能感兴趣的人的工作版本,它有点难看......
template <typename T>
struct ptr_traits {
using supports_deref = std::false_type;
};
template <typename T>
struct ptr_traits<T*> {
using supports_deref = std::true_type;
};
template <typename T>
struct ptr_traits<std::unique_ptr<T>> {
using supports_deref = std::true_type;
};
template <typename T>
struct ptr_traits<std::shared_ptr<T>> {
using supports_deref = std::true_type;
};
template <typename T>
using type_supports_deref_t = typename ptr_traits<typename std::remove_reference<typename std::remove_cv<T>::type>::type>::supports_deref;
template <typename T>
T& foo_impl(T&& t, std::false_type){
std::cout<<"No-ptr .. \n";
return t;
}
template <typename T>
auto foo_impl(T&& t, std::true_type) -> decltype(*t){
std::cout<<"Ptr .. \n";
return *t;
}
template <typename T>
auto foo(T&& t) -> decltype(foo_impl(t, type_supports_deref_t<T>{})){
return foo_impl(t, type_supports_deref_t<T>{});
}