Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 推断函数返回的类型的常量_C++_C++11_Constants_Return Value - Fatal编程技术网

C++ 推断函数返回的类型的常量

C++ 推断函数返回的类型的常量,c++,c++11,constants,return-value,C++,C++11,Constants,Return Value,有没有办法判断函数是返回常量值还是非常量值decltype适用于引用,但不适用于非引用类型 #include <type_traits> template< typename > struct print_type; //undefined int main(){ auto lambda = []()->const int{ return 0; }; print_type< decltype(lambda()) > dt; //

有没有办法判断函数是返回常量值还是非常量值
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;
}
#包括
模板
结构打印类型//未定义
int main(){
自动lambda=[]()->const int{return 0;};
打印类型dt;//打印类型
打印类型ro;
//打印类型
返回0;
}

我实现了一个
std::tuple
转换函数,它将调用每个tuple元素上的函数对象,并将结果存储在由返回类型组成的新
tuple
中。这不适用于常量返回类型,这非常令人惊讶(但需要)。

您可以使用std::result\u of来获取可调用对象的返回类型


请记住,返回常量int是不可能的,编译器将忽略限定条件。GCC对此有一个警告。Wall-Wextra-pedantic中的某些东西会打开它。

对于非内置类型,您可以使用
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;
}
#包括
#包括
结构A{};
int main()
{
std::cout A{return A();};
标准::cout

decltype
不会保持返回值的
常量(正如您所注意到的)。对于非类、非数组类型,没有办法(我知道,我总是能保持希望)。对于类类型来说,这很简单。在您的示例中,
int
显然既不是类类型,也不是数组类型。很好。您能解释一下,或者指向某个地方,解释一下,给定lambda函数,
C
是如何推导出来的吗?在我看来,这个技巧对于闭包不起作用,因为它不能隐式转换为函数指针。Ver但是很好,也很有用。而且……因为我们获取了一个成员函数的地址,这对于重载的
operator()
@tsuki:现在呢?@Yakk: false true
#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