有没有办法在C ++中确定变量的类型是指针还是任何带有重载的operator*
的迭代器?
有标准的std::is_pointer
,但它没有提到迭代器。
我想在这样的代码中使用它:
template<class T>
void func(T var)
{
if constexpr (can_be_dereferenced<T>::value)
{
// do something with *var;
}
}
你基本上想检查*var
是否有效。这是SFINAE支票的完美用例:
#include <type_traits>
#include <utility>
namespace detail {
// If `*(object of type T)` is valid, this is selected and
// the return type is `std::true_type`
template<class T>
decltype(static_cast<void>(*std::declval<T>()), std::true_type{})
can_be_dereferenced_impl(int);
// Otherwise the less specific function is selected,
// and the return type is `std::false_type`
template<class>
std::false_type can_be_dereferenced_impl(...);
}
template<class T>
struct can_be_dereferenced : decltype(detail::can_be_dereferenced_impl<T>(0)) {};
template<class T>
void func(T var)
{
if constexpr (can_be_dereferenced<T&>::value)
// Or can_be_dereferenced<decltype((var))>::value
{
auto&& dereferenced = *var;
// Use dereferenced
}
}
您可以使用编译时函数重载决策和SFINAE以这种方式执行此操作:
template<class T, typename = std::enable_if_t<std::is_pointer<T>::value>>
void func(T var)
{
// a pointer
}
template<class T, typename = std::enable_if_t<!std::is_pointer<T>::value>,
typename = T::value_type>
void func(T var)
{
// possibly an iterator
}
int main()
{
int *i = new int(11);
func(i); // Calls the first overload
std::vector<int> v;
std::vector<int>::const_iterator it = v.begin();
func(it); // Calls the second overload
func(2); // Fail, as there is no function for this argument.
[..]