‘std::filesystem’ has not been declared after including

It seems your C++17 compiler doesn’t include the standard filesystem header. One possible way to get around that: #ifndef __has_include static_assert(false, “__has_include not supported”); #else # if __cplusplus >= 201703L && __has_include(<filesystem>) # include <filesystem> namespace fs = std::filesystem; # elif __has_include(<experimental/filesystem>) # include <experimental/filesystem> namespace fs = std::experimental::filesystem; # elif __has_include(<boost/filesystem.hpp>) # include <boost/filesystem.hpp> … Read more

Is there a safe navigation operator for C++?

The best you can do is collapse all the member accesses into one function. This assumes without checking that everything is a pointer: template <class C, class PM, class… PMs> auto access(C* c, PM pm, PMs… pms) { if constexpr(sizeof…(pms) == 0) { return c ? std::invoke(pm, c) : nullptr; } else { return c … Read more

Avoiding extra move in make_unique/make_shared/emplace/etc for structures that use aggregate initialization

Instead of adding a constructor to your type that takes a factory function, instead create a new external factory object with a conversion operator to your type. With C++17, that takes minimal work: template <class F> struct factory { F f; operator invoke_result_t<F&>() { return f(); } }; template <class F> factory(F ) -> factory<F>; … Read more

Check if a type is passed in variadic template parameter pack

You’re looking for std::disjunction. It’s specified in N4564 [meta.logical]. #include <type_traits> template<typename T, typename… Ts> constexpr bool contains() { return std::disjunction_v<std::is_same<T, Ts>…>; } static_assert( contains<int, bool, char, int, long>()); static_assert( contains<bool, bool, char, int, long>()); static_assert( contains<long, bool, char, int, long>()); static_assert(not contains<unsigned, bool, char, int, long>()); Live demo Or, adapted to a struct template<typename … Read more

Can I use the result of a C++17 captureless lambda constexpr conversion operator as a function pointer template non-type argument?

This is a gcc bug, filed 83258. In C++14, we used to have a linkage requirement for non-type template parameters of pointer type. But in C++17 (as a result of N4268), the parameter just needs to be a converted constant expression of the correct type, with a few other restrictions (none of which are relevant … Read more

What changes to C++ made copy initialization work for class with explicit constructor?

Because the behavior of copy elision changes from C++17; for this case copy elision is mandatory. Mandatory elision of copy/move operations Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly … Read more

Will I be able to declare a constexpr lambda inside a template parameter?

No, that is a compiler bug. gcc 7.1 correctly rejects the code. [expr.prim.lambda]/2: A lambda-expression is a prvalue whose result object is called the closure object. A lambda-expression shall not appear in an unevaluated operand, in a template-argument, in an alias-declaration, in a typedef declaration, or in the declaration of a function or function template … Read more

What are the differences between std::variant and boost::variant?

Assignment/emplacement behavior: boost::variant may allocate memory when performing assignment into a live variant. There are a number of rules that govern when this can happen, so whether a boost::variant will allocate memory depends on the Ts it is instantiated with. std::variant will never dynamically allocate memory. However, as a concession to the complex rules of … Read more