暂时先不更新前一篇文章了,感觉那个文章要写好久。累死。
今天说一说C++右值引用的一个问题。
这个问题的发现也是很偶然的。
来一段毫无意义但是能证明问题的代码:
1 std::string && 2 get_string() 3 { 4 return "hello world"; 5 } 6 7 int main() 8 { 9 auto s1 = get_string(); 10 auto const s2 = get_string(); 11 auto const & s3 = get_string(); 12 13 std::cout << s1 << std::endl; 14 std::cout << s2 << std::endl; 15 std::cout << s3 << std::endl; 16 17 return 0; 18 }
请问控制台输出神马?
自己跑一跑看一看,然后咱们下一个结论:
!!返回值不要搞成右值引用的样子!!
当然了,在这个简单的案例里面,你还能看到编译器报警。但是复杂的时候可能就看不到了。这个问题发生在我自己封装的访问optional::value()的函数里:
1 template <typename T> 2 T && 3 value(optional<T> && v) 4 { 5 #if defined TKAT_APPLE_CLANG && TKAT_APPLE_CLANG <= 9020039 6 // https://stackoverflow.com/questions/44217316/how-do-i-use-stdoptional-in-c 7 return std::move(*std::move(v)); 8 #else 9 10 # if !defined NDEBUG 11 try 12 { 13 return std::move(v).value(); 14 } 15 catch (std::bad_optional_access const & eh) 16 { 17 TKAT_LOG_TEST_ENVIRONMENT(eh.what()); 18 throw; 19 } 20 # else 21 return std::move(v).value(); 22 # endif 23 24 #endif 25 }
完!