c++17

Class template argument deduction and default template parameters

Deadly 提交于 2019-12-03 10:40:05
The following stripped down code doesn't work with the latest clang++5 but is accepted by g++7: template<typename Wrapped, typename U> struct wrapper; template<typename Wrapped, typename U=int> struct wrapper { wrapper() = default; // Automatic deduction guide constexpr explicit wrapper(Wrapped) noexcept {} }; int main() { struct {} dummy; constexpr auto wrapped = wrapper(dummy); } It fails with the following error messages: <source>:18:30: error: no viable constructor or deduction guide for deduction of template arguments of 'wrapper' constexpr auto wrapped = wrapper(dummy); ^ <source>:12:24:

Must a c++ interface obey the rule of five?

别来无恙 提交于 2019-12-03 10:39:28
What is the correct way to declare instantiation methods when defining an interface class? Abstract base classes are required to have a virtual destructor for obvious reasons. However, the following compilation warning is then given: "'InterfaceClass' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator", which is the 'rule of five'. I understand why the 'rule of five' should be obeyed in general, but is it still applicable for an abstract base class or interface? My implimentation is then: class

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

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-03 10:37:19
std::make_unique() (and similar functions) have a little problem : #include <cstdio> #include <memory> using namespace std; struct S { S() { printf("ctor\n"); } ~S() { printf("dtor\n"); } S(S const&) { printf("cctor\n"); } S(S&&) { printf("mctor\n"); } }; S foo() { return S(); } int main() { { printf("--------------- case 1 ---------------\n"); unique_ptr<S> s1 = make_unique<S>( foo() ); } { printf("--------------- case 2 ---------------\n"); unique_ptr<S> s2 { new S( foo() ) }; } } Output: --------------- case 1 --------------- ctor mctor dtor dtor --------------- case 2 --------------- ctor

Why is gcc failing when using lambda for non-type template parameter?

别来无恙 提交于 2019-12-03 10:34:54
The following snippet compiles with no error with Clang 4.0 but GCC 7.0 produces errors (note the use of -std=c++1z flag). using FuncT = int (*)(double); template <FuncT FUNC> int temp_foo(double a) { return FUNC(a); } int foo(double a) { return 42; } void func() { auto lambda = [](double a) { return 5; }; struct MyStruct { static int foo(double a) { return 42; } }; temp_foo<foo>(3); temp_foo<static_cast<FuncT>(lambda)>(3); temp_foo<MyStruct::foo>(3); } Specifically, GCC complains that both the lambda and the nested class's method have no linkage, so they can't be used as a non-type template

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

十年热恋 提交于 2019-12-03 10:27:08
问题 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? 回答1: 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

Fold expressions with arbitrary callable?

我的梦境 提交于 2019-12-03 10:23:21
Looking over the C++17 paper on folds, (and on cppreference ), I'm confused as to why the choice was made to only work with operators? At first glance it seems like it would make it easier to expand (... + args) by just shoving a + token between the elements of args , but I'm unconvinced this is a great decision. Why can't a binary lambda expression work just as well and follow the same expansion as the latter above? It's jarring to me that a fold syntax would be added to a language without support for arbitrary callables, so does the syntax allow a way to use them that I'm just not seeing?

Is this a bug? Constexpr constructor silently becomes non-constexpr

三世轮回 提交于 2019-12-03 10:13:11
Look at this code: struct NonConstexpr { NonConstexpr() { } }; template <typename T> struct Bar { NonConstexpr nonConstexpr; constexpr Bar() { } }; struct Foo { Bar<void> bar; constexpr Foo() { } }; Foo has a member, Foo::bar::nonConstexpr , which has a non-constexpr constructor. So, my expectation is that this should not compile. But it compiles with gcc, clang and msvc. Is this a compiler bug, or some rule allows this code to compile? If I add a NonConstexpr member into Foo directly, the code doesn't compile anymore. (I got this problem, because I've expected static initialization for a

Return Optional value with ?: operator

倾然丶 夕夏残阳落幕 提交于 2019-12-03 10:10:23
I often need to use optional type for functions: std::optional<int32_t> get(const std::string& field) { auto it = map.find(field); if (it != map.end()) return it->second; return {}; } Is there a way to return optional value in one line? e.g. this: std::optional<int32_t> get(const std::string& field) { auto it = map.find(field); return it != map.end() ? it->second : {}; } results in the error error: expected primary-expression before '{' token return it != map.end() ? it->second : {}; ^ You can explicitly wrap the some-value return into an std::optional , and fall back on the constexpr std:

Stripping all qualifiers from a function type

孤街醉人 提交于 2019-12-03 10:06:17
Given a possibly varargs function type with possibly a cv-qualifier-seq and possibly a ref-qualifier , is it possible to write a type trait that strips all the qualifiers without writing 4 * 3 * 2 = 24 partial specializations? template<class T> struct strip_function_qualifiers; template<class R, class... Args> struct strip_function_qualifiers<R(Args...)> { using type = R(Args...); }; template<class R, class... Args> struct strip_function_qualifiers<R(Args..., ...)> { using type = R(Args..., ...); }; template<class R, class... Args> struct strip_function_qualifiers<R(Args...) const> { using

Cv-qualifications of prvalues (revisited)

好久不见. 提交于 2019-12-03 10:03:07
This is a followup to my previous question , where the apparent consensus was that the change in treatment of cv-qualifications of prvalues was just a fairly minor and inconsequential change intended to solve some inconsistencies (e.g. functions returning prvalues and declared with cv-qualified return types). However, I see another place in the standard that appears to rely on prvalues having cv-qualified types: initialization of const references with prvalues through temporary materialization conversion . The relevant wording can be found in multiple spots in 9.3.3/5 [...] If the converted