有没有办法判断函数是返回const还是非const值? decltype
适用于引用,但它不适用于非引用类型。
#include <type_traits>
template< typename >
struct print_type; //undefined
int main(){
auto lambda = []()->const int{ return 0; };
print_type< decltype(lambda()) > dt; //print_type< int >
print_type< typename std::result_of<decltype(lambda)()>::type > ro;
//print_type< int >
return 0;
}
我实现了一个std::tuple
转换函数,它将在每个元组元素上调用一个函数对象,并将结果存储在由返回类型组成的新tuple
中。这对const返回类型不起作用,这是非常令人惊讶的(但需要)。
答案 0 :(得分:5)
对于非内置类型,您可以使用std::is_const
和decltype
来获得所需内容。
示例:
#include <iostream>
#include <type_traits>
struct A {};
int main()
{
std::cout << std::boolalpha;
{
auto lambda = []()->A{ return A(); };
std::cout << std::is_const<decltype(lambda())>::value << std::endl;
}
{
auto lambda = []()->const A{ return A(); };
std::cout << std::is_const<decltype(lambda())>::value << std::endl;
}
return 0;
}
输出:
false true
答案 1 :(得分:3)
#include <iostream>
#include <type_traits>
#include <utility>
template <typename T>
struct has_operator
{
template <typename U>
struct SFINAE {};
template <typename U>
static std::true_type test(SFINAE<decltype(&U::operator())>*);
template <typename U>
static std::false_type test(...);
static constexpr bool value = std::is_same<decltype(test<T>(nullptr)), std::true_type>::value;
};
template <bool value, typename T>
struct check_constness;
template <typename T>
struct check_constness<false, T>
{
template <typename R, typename... Args>
static std::true_type const_or_not(const R(*)(Args...));
static std::false_type const_or_not(...);
using type = decltype(const_or_not(std::declval<T*>()));
};
template <typename T>
struct check_constness<true, T>
{
template <typename R, typename C, typename... Args>
static std::true_type const_or_not(const R(C::*)(Args...));
template <typename R, typename C, typename... Args>
static std::true_type const_or_not(const R(C::*)(Args...) const);
template <typename R, typename C, typename... Args>
static std::true_type const_or_not(const R(C::*)(Args...) const volatile);
template <typename R, typename C, typename... Args>
static std::true_type const_or_not(const R(C::*)(Args...) volatile);
static std::false_type const_or_not(...);
using type = decltype(const_or_not(&T::operator()));
};
template <typename T>
using is_const_ret_type = typename check_constness<has_operator<T>::value, T>::type;
int glob() { return 0; }
const int cglob() { return 0; }
int main()
{
std::cout << std::boolalpha;
int x = 123;
auto lambda = []() -> int { return 0; };
auto clambda = []() -> const int { return 0; };
auto closure = [x]() -> int { return x; };
auto cclosure = [x]() -> const int { return x; };
std::cout << is_const_ret_type<decltype(lambda)>::value << std::endl;
std::cout << is_const_ret_type<decltype(clambda)>::value << std::endl;
std::cout << is_const_ret_type<decltype(glob)>::value << std::endl;
std::cout << is_const_ret_type<decltype(cglob)>::value << std::endl;
std::cout << is_const_ret_type<decltype(closure)>::value << std::endl;
std::cout << is_const_ret_type<decltype(cclosure)>::value << std::endl;
}
输出:
false
true
false
true
false
true
答案 2 :(得分:0)
您可以使用std :: result_of来获取可调用对象的返回类型。
请记住,返回const int是不可能的,编译器将忽略限定。海湾合作委员会对此发出警告。 -Wall -Wextra -pedantic中的东西会打开它。