c++17

Why can a dependent name be considered as complete even if the actual type is not defined until the very end

允我心安 提交于 2020-01-13 08:20:09
问题 Consider this example: template <class T> void Yeap(T); int main() { Yeap(0); return 0; } template <class T> void YeapImpl(); struct X; template <class T> void Yeap(T) { YeapImpl<X>(); // pass X to another template } template <class T> void YeapImpl() { T().foo(); } struct X { void foo() {} }; Note that struct X is not defined until the very end. I used to believe that all odr-used names must be complete at the point of the instantiation. But here, how can the compiler treat it as a complete

Understanding this highly templated C++ function binder

☆樱花仙子☆ 提交于 2020-01-13 05:53:32
问题 template<typename Container, typename Ret, typename ...Args> struct BindImpl { template<Ret (Container::*MemberFunc)(Args...)> class Callable { public: inline constexpr Callable (Container *container) : m_container(container) {} inline Ret operator() (Args ...args) const { return (m_container->*MemberFunc)(std::forward<Args>(args)...); } inline Function<Ret(Args...)> toFunction() const { return Function<Ret(Args...)>(*this); } private: Container *m_container; }; }; template<typename Container

Avoid calling move constructor

吃可爱长大的小学妹 提交于 2020-01-12 13:48:08
问题 I have following example #include <cstdint> class FooC { public: FooC(uint16_t iPort, uint16_t iPin) : PORT(iPort) , PIN(iPin) { }; ~FooC() = default; FooC() = delete; FooC(const FooC&) = delete; FooC(FooC&&) = delete; private: const uint16_t PORT; const uint16_t PIN; }; int main() { FooC array[2] = { FooC(1,2), FooC(3,4) }; } and I don't want to call the default, move and copy constructor. Due to that I deleted the functions. Unfortunately this results in following error (compiled with C++11

std::optional - construct empty with {} or std::nullopt?

戏子无情 提交于 2020-01-12 06:28:11
问题 I thought that initializing a std::optional with std::nullopt would be the same as default construction. They are described as the same at cppreference, as form (1) However, both Clang and GCC seem to treat these toy example functions differently. #include <optional> struct Data { char large_data[0x10000]; }; std::optional<Data> nullopt_init() { return std::nullopt; } std::optional<Data> default_init() { return {}; } Compiler Explorer seems to imply that using std::nullopt will simply set the

std::optional - construct empty with {} or std::nullopt?

♀尐吖头ヾ 提交于 2020-01-12 06:28:08
问题 I thought that initializing a std::optional with std::nullopt would be the same as default construction. They are described as the same at cppreference, as form (1) However, both Clang and GCC seem to treat these toy example functions differently. #include <optional> struct Data { char large_data[0x10000]; }; std::optional<Data> nullopt_init() { return std::nullopt; } std::optional<Data> default_init() { return {}; } Compiler Explorer seems to imply that using std::nullopt will simply set the

Different results in Clang and GCC when casting to std::optional<T>

拟墨画扇 提交于 2020-01-12 06:26:10
问题 Given the following code: #include <iostream> #include <optional> struct foo { explicit operator std::optional<int>() { return std::optional<int>( 1 ); } explicit operator int() { return 0; } }; int main() { foo my_foo; std::optional<int> my_opt( my_foo ); std::cout << "value: " << my_opt.value() << std::endl; } gcc 7.2.0 writes value: 1 . MSVC 2017 (15.3) and clang 4.0.0 however write value: 0 . Which one is correct according to the C++ standard? 回答1: Since this is direct-initialization, we

c_str() vs. data() when it comes to return type

房东的猫 提交于 2020-01-12 04:12:11
问题 After C++11, I thought of c_str() and data() equivalently. C++17 introduces an overload for the latter, that returns a non-constant pointer (reference, which I am not sure if it's updated completely w.r.t. C++17): const CharT* data() const; (1) CharT* data(); (2) (since C++17) c_str() does only return a constant pointer: const CharT* c_str() const; Why the differentiation of these two methods in C++17, especially when C++11 was the one that made them homogeneous? In other words, why only the

c_str() vs. data() when it comes to return type

本小妞迷上赌 提交于 2020-01-12 04:12:08
问题 After C++11, I thought of c_str() and data() equivalently. C++17 introduces an overload for the latter, that returns a non-constant pointer (reference, which I am not sure if it's updated completely w.r.t. C++17): const CharT* data() const; (1) CharT* data(); (2) (since C++17) c_str() does only return a constant pointer: const CharT* c_str() const; Why the differentiation of these two methods in C++17, especially when C++11 was the one that made them homogeneous? In other words, why only the

Implementing std::variant converting constructor - or: how to find first overload of all conversions from any T to Ti from parameter pack

ε祈祈猫儿з 提交于 2020-01-12 03:27:30
问题 In the latest working draft (page 572) of the C++ standard the converting constructor of std::variant is annotated with: template <class T> constexpr variant(T&& t) noexcept(see below ); Let Tj be a type that is determined as follows: build an imaginary function FUN (Ti) for each alternative type Ti. The overload FUN (Tj) selected by overload resolution for the expression FUN (std::forward<T>(t)) defines the alternative Tj which is the type of the contained value after construction. Effects:

Is there any hope to call a common base class method on a std::variant efficiently?

一曲冷凌霜 提交于 2020-01-12 03:11:07
问题 The way std::variant dispatches to different visitor methods when std::visit is called is pretty reasonable when the variant alternatives are completely different types. Essentially a visitor-specific vtable is built at compile-time and after some error checking 1 the appropriate visitor function is looked by indexing the table based the current index() which resolves to something like an indirect jump on most platforms. If the alternatives share a common base class, however, calling a (non