c++17

Overloading multiple function objects by reference

非 Y 不嫁゛ 提交于 2019-12-03 01:02:44
问题 In C++17, it is trivial to implement an overload(fs...) function that, given any number of arguments fs... satisfying FunctionObject, returns a new function object that behaves like an overload of fs... . Example: template <typename... Ts> struct overloader : Ts... { template <typename... TArgs> overloader(TArgs&&... xs) : Ts{forward<TArgs>(xs)}... { } using Ts::operator()...; }; template <typename... Ts> auto overload(Ts&&... xs) { return overloader<decay_t<Ts>...>{forward<Ts>(xs)...}; } int

Why doesn't this “undefined extern variable” result in a linker error in C++17?

删除回忆录丶 提交于 2019-12-03 00:58:49
I have compiled and ran the following program in a C++17 compiler (Coliru). In the program, I declared an extern variable, but did not define it. However, the compiler doesn't give a linker error . #include <iostream> extern int i; // Only declaration int func() { if constexpr (true) return 0; else if (i) return i; else return -1; } int main() { int ret = func(); std::cout<<"Ret : "<<ret<<std::endl; } Why doesn't the compiler give a linker error? Because the variable isn't odr-used. You have a constexpr if there that always discards the branch that could use it. One of the points of constexpr

Why doesn't `std::stringstream::stringstream(std::string&&)` exist?

﹥>﹥吖頭↗ 提交于 2019-12-03 00:55:02
I was hoping stringstream has a constructor that steals its initial content from a string&& . Do such inter-species "move constructors" generally not exist in the STL? If not, why not? There's history, which is disappointing. But also a future that looks bright. When move semantics went into C++11, it was huge, controversial, and overwhelming. I wanted to be able to move strings into and out of stringstream . However the politics at the time demanded that the internal store did not have to be a basic_string<charT> . For example the internal store could be a vector . And there was no ability to

How to make `short-circuit evaluation` also available in `fold expressions`?

五迷三道 提交于 2019-12-03 00:35:35
#include <type_traits> #define FORWARD(arg)\ std::forward<decltype(arg)>(arg) template<typename... Args> constexpr bool AndL(Args&&... args) { return (... && FORWARD(args)); } template<typename... Args> constexpr bool AndR(Args&&... args) { return (FORWARD(args) && ...); } int main() { bool* pb = nullptr; false && (*pb = true); // ok at runtime. AndL(false, (*pb = true)); // error at runtime! AndR(false, (*pb = true)); // error at runtime! } The traditional && operator supports short-circuit evaluation , so false && (*pb = true) will be ok at runtime, but the following two cases are not. How

When does type information flow backwards in C++?

社会主义新天地 提交于 2019-12-03 00:29:27
问题 I just watched Stephan T. Lavavej talk at CppCon 2018 on "Class Template Argument Deduction", where at some point he incidentally says: In C++ type information almost never flows backwards ... I had to say "almost" because there's one or two cases, possibly more but very few . Despite trying to figure out which cases he might be referring to, I couldn't come up with anything. Hence the question: In which cases the C++17 standard mandates that type information propagate backwards? 回答1: Here is

std::ptr_fun replacement for c++17

我与影子孤独终老i 提交于 2019-12-03 00:22:40
I am using std::ptr_fun as follows: static inline std::string &ltrim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); return s; } as presented in this answer . However this does not compile with C++17 (using Microsoft Visual Studio 2017), with the error: error C2039: 'ptr_fun': is not a member of 'std' How can this be fixed? You use a lambda: static inline std::string &ltrim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) {return !std::isspace(c);})); return s; } The answer you cited is from

How to properly access mapped memory without undefined behavior in C++

浪尽此生 提交于 2019-12-02 23:54:55
I've been trying to figure out how to access a mapped buffer from C++17 without invoking undefined behavior. For this example, I'll use a buffer returned by Vulkan's vkMapMemory . So, according to N4659 (the final C++17 working draft), section [intro.object] (emphasis added): The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is created by a definition (6.1), by a new-expression (8.3.4), when implicitly changing the active member of a union (12.3), or when a temporary object is created (7.4, 15.2). These are, apparently, the only valid ways to

Why is std::shared_ptr::unique() deprecated?

久未见 提交于 2019-12-02 23:33:27
What is the technical problem with std::shared_ptr::unique() that is the reason for its deprecation in C++17? According to cppreference.com , std::shared_ptr::unique() is deprecated in C++17 as this function is deprecated as of C++17 because use_count is only an approximation in multi-threaded environment. I understand this to be true for use_count() > 1 : While I'm holding a reference to it, someone else might simultaneously let go of his or create a new copy. But if use_count() returns 1 (which is what I'm interested in when calling unique() ) then there is no other thread that could change

Does the behavior of guaranteed copy elision depend on existence of user-defined copy constructor?

醉酒当歌 提交于 2019-12-02 22:52:13
The following code behaves differently with or without user-defined copy constructor under GCC 8.0.1 : #include <cassert> struct S { int i; int *p; S() : i(0), p(&i) {} // S(const S &s) : i(s.i), p(&i) {} // #1 // S(const S &s) : i(s.i), p(s.p) {} // #2 // S(const S &s) = delete; // #3 }; S make_S() {return S{};} int main() { S s = make_S(); assert(s.p == &s.i); } With either of the commented user-defined copy constructors (even with #2, the one performing a simple shallow copy), the assertion will not fail, which means guaranteed copy elision works as expected. However, without any user

Usefulness of std::make_pair and std::make_tuple in C++1z

喜你入骨 提交于 2019-12-02 22:18:23
In my understanding, the sole reason for the existence of std::make_pair and std::make_tuple is that you don't have to write the types by yourself as they are automatically deduced. In C++1z, we have template argument deduction for class templates , which allows us to simply write std::pair p(1, 2.5); // C++1z instead of auto p = std::make_pair(1, 2.5); // C++11/14 The situation for std::tuple is analogous. This leads to the following question: In C++1z, is there a situation in which it is beneficial to use std::make_pair and std::make_tuple instead of using the constructors of std::pair and