Detailed presentation of universal references and perfect forwarding introduced in C++11.
Extended version of "Hot C++11, Part 3 Universal References And Perfect Forwarding".
Escaping The Jar hell with Jigsaw LayersNikita Lipsky
Jigsaw modules are often criticized for the lack of versioning that exists in alternative module systems for Java, such as OSGi. One of the main purposes of versioning is to solve the so called Jar Hell problem that arises when your application depends on two different versions of the same library. While Jigsaw is able to detect this conflicting situation, it won’t allow you to load both versions that are placed on the module path. However, it is not always possible to eliminate all version conflicts from your application, because other versions of the same libraries can come to your application indirectly via dependencies that you do not control. Fortunately, there is a native solution for the problem in Jigsaw called Layers. In this session, I will show what problems Jigsaw could have introduced if it had explicit versions for modules, and how Jigsaw Layers in conjunction with Jigsaw Services help to solve the Jar Hell problem safely.
CloudNative Days Spring 2021 ONLINE キーノートでの発表資料です。
https://event.cloudnativedays.jp/cndo2021/talks/1071
本セッションでは、DockerとKubernetesのもつ基本的な機能の概要を、コンテナの仕組みをふまえつつイラストを用いて紹介していきます。一般にあまり焦点をあてて取り上げられることは多くありませんが、コンテナの作成や管理を担う低レベルなソフトウェア「コンテナランタイム」も本セッションの中心的なトピックのひとつです。
本セッションは、拙著「イラストで分かるDockerとKubernetes」(技術評論社)の内容を参考にしています。
https://www.amazon.co.jp/dp/4297118378
Escaping The Jar hell with Jigsaw LayersNikita Lipsky
Jigsaw modules are often criticized for the lack of versioning that exists in alternative module systems for Java, such as OSGi. One of the main purposes of versioning is to solve the so called Jar Hell problem that arises when your application depends on two different versions of the same library. While Jigsaw is able to detect this conflicting situation, it won’t allow you to load both versions that are placed on the module path. However, it is not always possible to eliminate all version conflicts from your application, because other versions of the same libraries can come to your application indirectly via dependencies that you do not control. Fortunately, there is a native solution for the problem in Jigsaw called Layers. In this session, I will show what problems Jigsaw could have introduced if it had explicit versions for modules, and how Jigsaw Layers in conjunction with Jigsaw Services help to solve the Jar Hell problem safely.
CloudNative Days Spring 2021 ONLINE キーノートでの発表資料です。
https://event.cloudnativedays.jp/cndo2021/talks/1071
本セッションでは、DockerとKubernetesのもつ基本的な機能の概要を、コンテナの仕組みをふまえつつイラストを用いて紹介していきます。一般にあまり焦点をあてて取り上げられることは多くありませんが、コンテナの作成や管理を担う低レベルなソフトウェア「コンテナランタイム」も本セッションの中心的なトピックのひとつです。
本セッションは、拙著「イラストで分かるDockerとKubernetes」(技術評論社)の内容を参考にしています。
https://www.amazon.co.jp/dp/4297118378
Title: Working Remotely (via SSH) Rocks!
Intro: Consistent & Persistent development environment from any location any client.
"SSH + TMUX + CLI" Rocks!
Nice material about "SSH Tunneling": http://www.slideshare.net/osoco/ssh-tunneling-recipes-10284950
Programming is hard. Programming correct C and C++ is particularly hard. Indeed, both in C and certainly in C++, it is uncommon to see a screenful containing only well defined and conforming code.Why do professional programmers write code like this? Because most programmers do not have a deep understanding of the language they are using.While they sometimes know that certain things are undefined or unspecified, they often do not know why it is so. In these slides we will study small code snippets in C and C++, and use them to discuss the fundamental building blocks, limitations and underlying design philosophies of these wonderful but dangerous programming languages.
This content has a CC license. Feel free to use it for whatever you want. You may download the original PDF file from: http://www.pvv.org/~oma/DeepC_slides_oct2012.pdf
Bob Tiernay explores the fascinating world of jq, "the JSON Processor”. Starting with a motivation, he then covers the language, provides helpful tips, showcases a real world example, cautions some things to avoid and finishes with a discussion of the ecosystem.
••• Boost your code's performances using C++11 new features! •••
In this presentation you will learn:
▸ the difference between an Lvalue and Rvalue
▸ how to use std::move, std::forward, noexcept
▸ how to implement move semantics to avoid useless copies
▸ how to implement perfect forwarding for the factory pattern
This is my attempt at a look at some of the features of C++11, and more importantly, describing some of the style changes in C++11 that will make programmers more productive and programs more efficient.
Title: Working Remotely (via SSH) Rocks!
Intro: Consistent & Persistent development environment from any location any client.
"SSH + TMUX + CLI" Rocks!
Nice material about "SSH Tunneling": http://www.slideshare.net/osoco/ssh-tunneling-recipes-10284950
Programming is hard. Programming correct C and C++ is particularly hard. Indeed, both in C and certainly in C++, it is uncommon to see a screenful containing only well defined and conforming code.Why do professional programmers write code like this? Because most programmers do not have a deep understanding of the language they are using.While they sometimes know that certain things are undefined or unspecified, they often do not know why it is so. In these slides we will study small code snippets in C and C++, and use them to discuss the fundamental building blocks, limitations and underlying design philosophies of these wonderful but dangerous programming languages.
This content has a CC license. Feel free to use it for whatever you want. You may download the original PDF file from: http://www.pvv.org/~oma/DeepC_slides_oct2012.pdf
Bob Tiernay explores the fascinating world of jq, "the JSON Processor”. Starting with a motivation, he then covers the language, provides helpful tips, showcases a real world example, cautions some things to avoid and finishes with a discussion of the ecosystem.
••• Boost your code's performances using C++11 new features! •••
In this presentation you will learn:
▸ the difference between an Lvalue and Rvalue
▸ how to use std::move, std::forward, noexcept
▸ how to implement move semantics to avoid useless copies
▸ how to implement perfect forwarding for the factory pattern
This is my attempt at a look at some of the features of C++11, and more importantly, describing some of the style changes in C++11 that will make programmers more productive and programs more efficient.
COM1407: Type Casting, Command Line Arguments and Defining Constants Hemantha Kulathilake
At the end of this lecture students should be able to;
Define type cast and type promotion in C programming language.
Define command line arguments in C Programming language.
Declare constants according to the C programming.
Apply math.h header file for problem solving.
Apply taught concepts for writing programs.
Welcome the the next GRCPP meetup where we will introduce a powerful new feature in C++20: Concepts.
Concepts are a way to specify requirements on template parameter types and to make templates more expressive and easier to understand..
We will show how to use concepts to create "interfaces" for your template types, how to simplify your code and provide better error messages.
We will demonstrate how to use `requires` to create "contracts" for your templates and how to use `concept` to constrain the acceptable types.
GraphSummit Paris - The art of the possible with Graph TechnologyNeo4j
Sudhir Hasbe, Chief Product Officer, Neo4j
Join us as we explore breakthrough innovations enabled by interconnected data and AI. Discover firsthand how organizations use relationships in data to uncover contextual insights and solve our most pressing challenges – from optimizing supply chains, detecting fraud, and improving customer experiences to accelerating drug discoveries.
OpenMetadata Community Meeting - 5th June 2024OpenMetadata
The OpenMetadata Community Meeting was held on June 5th, 2024. In this meeting, we discussed about the data quality capabilities that are integrated with the Incident Manager, providing a complete solution to handle your data observability needs. Watch the end-to-end demo of the data quality features.
* How to run your own data quality framework
* What is the performance impact of running data quality frameworks
* How to run the test cases in your own ETL pipelines
* How the Incident Manager is integrated
* Get notified with alerts when test cases fail
Watch the meeting recording here - https://www.youtube.com/watch?v=UbNOje0kf6E
Graspan: A Big Data System for Big Code AnalysisAftab Hussain
We built a disk-based parallel graph system, Graspan, that uses a novel edge-pair centric computation model to compute dynamic transitive closures on very large program graphs.
We implement context-sensitive pointer/alias and dataflow analyses on Graspan. An evaluation of these analyses on large codebases such as Linux shows that their Graspan implementations scale to millions of lines of code and are much simpler than their original implementations.
These analyses were used to augment the existing checkers; these augmented checkers found 132 new NULL pointer bugs and 1308 unnecessary NULL tests in Linux 4.4.0-rc5, PostgreSQL 8.3.9, and Apache httpd 2.2.18.
- Accepted in ASPLOS ‘17, Xi’an, China.
- Featured in the tutorial, Systemized Program Analyses: A Big Data Perspective on Static Analysis Scalability, ASPLOS ‘17.
- Invited for presentation at SoCal PLS ‘16.
- Invited for poster presentation at PLDI SRC ‘16.
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppGoogle
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-fusion-buddy-review
AI Fusion Buddy Review: Key Features
✅Create Stunning AI App Suite Fully Powered By Google's Latest AI technology, Gemini
✅Use Gemini to Build high-converting Converting Sales Video Scripts, ad copies, Trending Articles, blogs, etc.100% unique!
✅Create Ultra-HD graphics with a single keyword or phrase that commands 10x eyeballs!
✅Fully automated AI articles bulk generation!
✅Auto-post or schedule stunning AI content across all your accounts at once—WordPress, Facebook, LinkedIn, Blogger, and more.
✅With one keyword or URL, generate complete websites, landing pages, and more…
✅Automatically create & sell AI content, graphics, websites, landing pages, & all that gets you paid non-stop 24*7.
✅Pre-built High-Converting 100+ website Templates and 2000+ graphic templates logos, banners, and thumbnail images in Trending Niches.
✅Say goodbye to wasting time logging into multiple Chat GPT & AI Apps once & for all!
✅Save over $5000 per year and kick out dependency on third parties completely!
✅Brand New App: Not available anywhere else!
✅ Beginner-friendly!
✅ZERO upfront cost or any extra expenses
✅Risk-Free: 30-Day Money-Back Guarantee!
✅Commercial License included!
See My Other Reviews Article:
(1) AI Genie Review: https://sumonreview.com/ai-genie-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
#AIFusionBuddyReview,
#AIFusionBuddyFeatures,
#AIFusionBuddyPricing,
#AIFusionBuddyProsandCons,
#AIFusionBuddyTutorial,
#AIFusionBuddyUserExperience
#AIFusionBuddyforBeginners,
#AIFusionBuddyBenefits,
#AIFusionBuddyComparison,
#AIFusionBuddyInstallation,
#AIFusionBuddyRefundPolicy,
#AIFusionBuddyDemo,
#AIFusionBuddyMaintenanceFees,
#AIFusionBuddyNewbieFriendly,
#WhatIsAIFusionBuddy?,
#HowDoesAIFusionBuddyWorks
We describe the deployment and use of Globus Compute for remote computation. This content is aimed at researchers who wish to compute on remote resources using a unified programming interface, as well as system administrators who will deploy and operate Globus Compute services on their research computing infrastructure.
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxrickgrimesss22
Discover the essential features to incorporate in your Winzo clone app to boost business growth, enhance user engagement, and drive revenue. Learn how to create a compelling gaming experience that stands out in the competitive market.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
Quarkus Hidden and Forbidden ExtensionsMax Andersen
Quarkus has a vast extension ecosystem and is known for its subsonic and subatomic feature set. Some of these features are not as well known, and some extensions are less talked about, but that does not make them less interesting - quite the opposite.
Come join this talk to see some tips and tricks for using Quarkus and some of the lesser known features, extensions and development techniques.
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
Mobile App Development Company In Noida | Drona InfotechDrona Infotech
Looking for a reliable mobile app development company in Noida? Look no further than Drona Infotech. We specialize in creating customized apps for your business needs.
Visit Us For : https://www.dronainfotech.com/mobile-application-development/
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus
As part of the DOE Integrated Research Infrastructure (IRI) program, NERSC at Lawrence Berkeley National Lab and ALCF at Argonne National Lab are working closely with General Atomics on accelerating the computing requirements of the DIII-D experiment. As part of the work the team is investigating ways to speedup the time to solution for many different parts of the DIII-D workflow including how they run jobs on HPC systems. One of these routes is looking at Globus Compute as a way to replace the current method for managing tasks and we describe a brief proof of concept showing how Globus Compute could help to schedule jobs and be a tool to connect compute at different facilities.
Navigating the Metaverse: A Journey into Virtual Evolution"Donna Lenk
Join us for an exploration of the Metaverse's evolution, where innovation meets imagination. Discover new dimensions of virtual events, engage with thought-provoking discussions, and witness the transformative power of digital realms."
2. Imagine a simple factory:
template<typename T, typename ???>
shared_ptr<T> makeShared(??? arg)
{
return shared_ptr<T>(new T(arg));
}
❖ The intent here is to pass the argument arg from the factory
function to T's constructor.
❖ Ideally, everything should behave just as if the factory function
weren't there and the constructor were called directly in the
client code i.e. a perfect forwarding.
Perfect Forwarding: The Problem
2
3. C++98 Solution
First approach is to take arg by const ref:
template<typename T, typename Arg>
shared_ptr<T> makeShared(const Arg& arg) {
return shared_ptr<T>(new T(arg));
}
std::string readFile();
makeShared<Foo>(readFile());
makeShared<Bar>(42);
Connection conn;
makeShared<Client>(conn);
// Compilation error: non-const lvalue ref passed
Overload for non-const ref should be added:
template<typename T, typename Arg>
shared_ptr<T> makeShared(Arg& arg) {
return shared_ptr<T>(new T(arg));
}
3
4. C++98 Solution
template<typename T, typename Arg>
shared_ptr<T> makeShared(const Arg& arg);
template<typename T, typename Arg>
shared_ptr<T> makeShared(Arg& arg);
Drawbacks:
❖ 2 overloads for one argument, 2^N overloads for N
arguments.
❖ Move semantics blocked in C++11.
- No more overloads, please!
4
6. Reference-Collapsing Rules
C++11 got new reference-collapsing rules in template instantiation context:
template<class T>
struct Collapse {
typedef T&& RvRef;
typedef T& LvRef;
}; typename Collapse<X&>::RvRef
• An rvalue reference to an rvalue reference becomes (collapses into) an
rvalue reference:
Collapse<X&&>::RvRef (X&& &&) → X&&
• Any other reference to reference (i.e., all combinations involving an
lvalue reference) collapses into an lvalue reference:
Collapse<X&&>::LvRef (X&& &) → X&
Collapse<X&>::RvRef (X& &&) → X&
Collapse<X&>::LvRef (X& &) → X&
❖ Reference-collapsing preserves cv-qualifiers of original type.
❖ It is still impossible to explicitly declare reference to reference.
6
7. Template Argument Deduction Rule
C++11 got special template argument deduction rule for
function templates:
template<typename T>
void foo(T&& t);
• When called with lvalue of type X then
T resolves to X& → argument type collapses into X&
• When called with rvalue of type X then
T resolves to X → argument type becomes X&&
7
8. Universal References
If a variable or parameter is declared to have type T&& for some
deduced type T, that variable or parameter is a universal reference.
— Scott Meyers, Universal References in C++11
template<typename T>
void foo(T&& t); // t is a universal reference
Of course, the name of typename does not matter,
it can be any type&&.
They are also known as forwarding references.
8
9. Universal References: Examples
template<typename Arg> // [1.1]
void foo(Arg&& arg);
arg is universal reference
void bar(Bar&& op); // [1.2]
std::string&& s = …; // [1.3]
Fully specified type ⇒ no type deduction, op and s are rvalue references
template<typename Arg> // [1.4]
void foo(const Arg&& arg);
Should be exactly type&& were type is deduced ⇒ arg is const rvalue
reference
template<typename Arg> // [1.5]
void foo(Arg& arg);
Should be type&& ⇒ arg is lvalue reference
9
10. Universal References: Examples
template<typename T>
class Vector {
Vector(Vector&& rhs); // [2.1]
…
void push_back(T&& t); // [2.2]
};
Fully specified type (When function is called the template is already
instantiated so Vector and T are “fixed”) ⇒ no type deduction, rhs and t
are rvalue references
template<typename T>
class Vector {
template<typename U> // [2.3]
Vector(U&& rhs);
…
};
rhs is universal reference
10
11. Universal References: Examples
template<typename T> // [3.1]
void print(std::vector<T>&& arg);
Should be exactly type&& were type is deduced ⇒ arg is rvalue
reference
template<typename... Args> // [3.2]
void foo(Args&&... args);
Parameter pack of universal references
auto&& i = …; // [3.3]
It is exactly type&& where type is deduced ⇒ i is universal reference
[](auto&& arg) {…}; // [3.4] C++14 lambda
It is exactly type&& where type is deduced ⇒ arg is universal
reference
11
12. std::forward
template<typename T>
void foo(T&& t) {
bar(std::forward<T>(t)));
}
❖ Forwards the argument to another function with preserving the
type, cv-qualifiers and value category (lvalue/rvalue).
❖ Somehow similar to std::move but should be applied only to
universal references
❖ std::forward is a conditional cast to rvalue (while std::move is
an unconditional one):
❖ Rvalue if applied to rvalue reference
❖ Lvalue if applied to lvalue reference
❖ Both do nothing at runtime
12
13. Perfect Forwarding: Solved!
Universal references and std::forward are a key:
template<typename T, typename Arg>
shared_ptr<T> makeShared(Arg&& arg)
{
return shared_ptr<T>(
new T(std::forward<Arg>(arg)));
}
❖ No overloads needed
❖ Forwarded arguments are exactly the same that was passed by
the caller.
❖ No copies or moves performed
13
14. Plays Nice With Variadic Templates
Perfectly forwards any number of arguments:
template<typename T, typename... Args>
shared_ptr<T> makeShared(Args&&... args)
{
return shared_ptr<T>(
new T(std::forward<Args>(args)...));
}
14
16. Don’t Confuse std::move With std::forward
❖ std::move is used to unconditionally cast rvalue reference (or something
need to be forced) to rvalue.
template<typename T, typename Arg>
shared_ptr<T> makeShared(Arg&& arg)
{
return shared_ptr<T>(
new T(std::move(arg))); // What is wrong?
}
Using std::move with universal reference may lead to unexpected
move from lvalue.
❖ std::forward is used to forward universal reference, i.e. to conditionally
cast one to rvalue. Using it with rvalue reference is excessively uncommon
and so confusing.
16
17. URefs And std::forward Go Together
A universal reference is [almost] always used in
combination with std::forward. If you see former
without latter or vice versa, look for error!
Remember its second name a forwarding reference.
17
template<typename T>
void logAndBar(T&& t) {
std::cout << t << ‘n’;
bar(std::forward<T>(t)));
}
template<typename T>
Foo makeFoo(T&& t) {
return std::forward<T>(t);
}
template<class T>
struct Wrapper {
…
template<class U>
Wrapper(int id, U&& v)
: m_id(id)
, m_val(std::forward<U>(v))
{}
};
18. Use URefs And std::forward Carefully
❖ template<class T>
void foo(T&& t) {
Bar b(std::forward<T>(t));
std::cout << t.value(); // What is wrong?
…
}
Do not use forwarded-away objects because they may be in moved-
from state.
❖ Remember that std::forward may act as std::move. Check
previous presentation for std::move and rvalue related concerns.
❖ Remember that universal reference may be either rvalue reference
or lvalue reference. Write code accordingly.
18
19. Avoid Overloading on URefs
Imagine that we want to differently process rvalues (first overload)
and lvalues (second one):
template<typename T>
void foo(T&& t) {… std::move(t); …} // [1] rvalues
template<typename T>
void foo(T const& t) {…} // [2] lvalues
std::string s = “wow”;
foo(s);
WTF, overload [1] is called! Only const lvalues go to [2], all the rest
including non-const lvalues go to [1] because it takes universal
reference ⇒ accepts everything ⇒ a better match for everything
except const lvalue ref.
19
20. Avoid Overloading on URefs
Imagine that we want to have overload for integers:
template<typename T>
void foo(T&& t) {…} // [1] general case
void foo(long t) {…} // [2] integers
short s = 42;
foo(s);
WTF, overload [1] is called! Only longs go to [2], all the rest
including integers that need to be promoted to long integer go to
[1] because it takes universal reference ⇒ accepts everything ⇒
a better match for everything except a long integer.
20
21. Avoid Overloading on URefs
❖ Problem’s root cause is that universal reference parameter is too
“greedy” (by purpose) so become a better match more frequently
than expected.
❖ There are some solutions (Partially stolen from Meyers’ book):
❖ Abandon overloading by using different function names or
different number of parameters.
❖ Pass by const reference instead of universal reference.
❖ Pass params that are movable and copyable by value (and get
rid of template that uses universal references at all)
❖ Tag dispatch
❖ Constrain template that uses universal references
21
22. Avoid Overloading on URefs: Tag Dispatch
Using of compile time dispatching to implement overloading for
rvalues and lvalues:
template<typename T>
void foo(T&& t)
{
foo_impl(std::forward<T>(t),
std::is_lvalue_reference<T>());
}
template<typename T>
void foo_impl(T&& t, std::true_type) {…} // lvalues
template<typename T>
void foo_impl(T&& t, std::false_type) {…} // rvalues
22
23. URefs And Copy Constructor
Consider the simple wrapper:
template<typename T>
struct Wrapper {
T m_value;
…
template<typename U> // Single arg for simplicity
explicit Wrapper(U&& u)
: m_value(std::forward<U>(u)) {}
};
The purpose is to allow to construct Wrapper with whatever wrapped
type constructor accepts:
Wrapper<std::string> hello_world(“Hello, World!”);
23
24. URefs And Copy Constructor
template<typename T>
struct Wrapper {
T m_value;
…
template<typename U>
explicit Wrapper(U&& u)
: m_value(std::forward<U>(u)) {}
};
Looks OK?
Wrapper<std::string> w1(“Hello, World!”);
Wrapper<std::string> w2(w1); // Compilation error
For non-const lvalue reference the forwarding constructor is a better
match than [generated] copy constructor:
Wrapper(const Wrapper& rhs);
24
25. URefs And Copy Constructor
❖ Copy assignment operator has the same issue.
❖ Variadic forwarding constructor has the same issue.
template<typename... Ts>
struct tuple
{
template<typename... Us>
explicit tuple(Us&&... us);
// May be chosen instead of copy constructor
…
};
25
26. Constraining URef Template
Possible solution is to disable forwarding constructor for Wrapper and derived types:
template<typename T>
struct Wrapper {
T m_value;
…
template<
typename U,
typename = disable_if_same_or_derived_t<Wrapper, U>>
explicit Wrapper(U&& u)
: m_value(std::forward<U>(u)) {}
};
template<typename Base, typename Derived>
using disable_if_same_or_derived_t =
std::enable_if_t<
!std::is_base_of<
Base,
std::decay_t<Derived>
>::value
>; // C++14. A bit more verbose in C++11
26
std::enable_if
metafunction is a convenient
way to leverage SFINAE to
conditionally remove functions
from overload resolution based
on type traits.
27. Constraining URef Template 2
Another solution is to enable forwarding constructor only for types that may be used to construct T:
template<typename T>
struct Wrapper {
T m_value;
…
template<
typename U,
typename = std::enable_if_t<std::is_constructible<T, U&&>::value>>
explicit Wrapper(U&& u)
: m_value(std::forward<U>(u)) {}
}; // C++14. A bit more verbose in C++11
Easily extended to any number of arguments:
template<typename T>
struct Wrapper {
T m_value;
…
template<
typename... U,
typename = std::enable_if_t<std::is_constructible<T, U&&...>::value>>
explicit Wrapper(U&&... u)
: m_value(std::forward<U>(u)...) {}
}; // C++14. A bit more verbose in C++11
27
28. Constraining URef Template 3
Another solution is to disable forwarding constructor for types that otherwise
convertible to Wrapper. Which is true for Wrapper and derived types, for types that
got a dedicated constructor and types that implement a conversion to Wrapper.
template<class T>
struct Wrapper {
T m_value;
…
template<
typename U,
typename = std::enable_if_t<!std::is_convertible<U&&, Wrapper>::value>>
explicit Wrapper(U&& u);
explicit Wrapper(const Bar& bar); // A dedicated constructor for Bar
};
template<class T>
struct Foo {
operator Wrapper<T> () const; // Foo<T> provides a conversion to Wrapper<T>
};
Bar bar;
Foo<std::string> foo;
Wrapper<std::string> w1(bar), w2(foo); // ^ C++14. A bit more verbose in C++11
28
29. Perfect Forwarding Failures
❖ Braced initializer. Compiler can not deduce the type.
makeShared<std::vector<int>>({1, 2, 3});
User has to explicitly specify a type:
makeShared<std::vector<int>>(
std::initialized_list<int>({1, 2, 3}));
or
auto list = {1, 2, 3};
makeShared<std::vector<int>>(list);
❖ Overloaded function and function template names. A set of
functions that compiler can not choose a right one from.
You have to explicitly choose one function by casting the function
to a specific function pointer type.
29
30. Perfect Forwarding Failures
❖ 0 or NULL as null pointers. They are deduced to integral type instead of
pointer type. Use nullptr instead (not only in this case but always!).
❖ Declaration-only static const and constexpr data. Causes linker error.
struct Calendar {
static const int numberOfMonths = 12;
…
};
makeShared<int>(Calendar::numberOfMonths);
User has to add a definition for the data or pass a copy:
makeShared<int>(int(Calendar::numberOfMonths));
❖ Non-const bit-field. Non-const reference cannot bind to a bit-field. User has
to pass a copy:
makeShared<int>(int(var.bitField));
30
31. Useful Links
Thomas Becker, Perfect Forwarding: The Problem
http://thbecker.net/articles/rvalue_references/section_07.html
Scott Meyers, Universal References
http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
Eric Niebler, Universal References and the Copy Constructor
http://ericniebler.com/2013/08/07/universal-references-and-the-copy-constructo/
(Im)perfect forwarding with variadic templates
stackoverflow.com/questions/13296461/imperfect-forwarding-with-variadic-
templates
C++11 Standard (final plus minor editorial changes)
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Scott Meyers, Effective Modern C++, (Item 1 & chapter 4)
31