Library: improve helper to deal with self-shadowing ctor (see: #963)
Whenever a class defines a single-arg templated constructor, there is danger to shadow the auto-generated copy operations, leading to insidious failures. Some months ago, I did the ''obvious'' and added a tiny helper, allowing to mask out the dangerous case when the ''single argument'' is actually the class itself (meaning, it is a copy invocation and not meant to go through this templated ctor... As this already turned out as tremendously helpful, I now extended this helper to also cover cases where the problematic constructor accepts variadic arguments, which is quite common with builder-helpers
This commit is contained in:
parent
fc084c1ca5
commit
be4d809a23
4 changed files with 24 additions and 5 deletions
|
|
@ -136,9 +136,28 @@ namespace meta {
|
|||
|
||||
|
||||
|
||||
namespace {
|
||||
template<typename...>
|
||||
struct _ExtractFirst
|
||||
{
|
||||
using Type = void;
|
||||
};
|
||||
template<typename X, typename...XS>
|
||||
struct _ExtractFirst<X,XS...>
|
||||
{
|
||||
using Type = X;
|
||||
};
|
||||
}
|
||||
/** helper to extract the first argument from a variadic arg pack, if any */
|
||||
template<typename...XS>
|
||||
using extractFirst_t = typename _ExtractFirst<XS...>::Type;
|
||||
|
||||
|
||||
|
||||
/** helper to prevent a template constructor from shadowing inherited copy ctors */
|
||||
template<typename ARG, class SELF>
|
||||
using disable_if_self = disable_if<std::is_same<std::remove_reference_t<ARG>, SELF>>;
|
||||
template<class SELF, typename ...ARGS>
|
||||
using disable_if_self = disable_if<std::is_same<std::remove_cv_t<std::remove_reference_t<extractFirst_t<ARGS...>>>
|
||||
, SELF>>;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ namespace lib {
|
|||
* - `void(RandomDraw&, ...)` : the function manipulates the current
|
||||
* instance, to control parameters dynamically, based on input.
|
||||
*/
|
||||
template<class FUN, typename =disable_if_self<FUN, RandomDraw>>
|
||||
template<class FUN, typename =disable_if_self<RandomDraw, FUN>>
|
||||
RandomDraw(FUN&& fun)
|
||||
: Lazy{Disabled()}
|
||||
, probability_{1.0}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ namespace gear {
|
|||
* this reference is dangling and using it further will
|
||||
* lead to SEGFAULT or memory corruption.
|
||||
*/
|
||||
template<class FUN, typename =disable_if_self<FUN, SpecialJobFun>>
|
||||
template<class FUN, typename =disable_if_self<SpecialJobFun, FUN>>
|
||||
explicit
|
||||
SpecialJobFun (FUN&& someFun)
|
||||
: _Handle{selfAttached (new SpecialExecutor(forward<FUN> (someFun)))}
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ namespace test{
|
|||
installInitialiser(fun, buildInit([](int){ return 0; }));
|
||||
}
|
||||
// prevent this ctor from shadowing the copy ctors //////TICKET #963
|
||||
template<typename FUN, typename =disable_if_self<FUN, LazyDemo>>
|
||||
template<typename FUN, typename =disable_if_self<LazyDemo, FUN>>
|
||||
LazyDemo (FUN&& someFun)
|
||||
: LazyInit{MarkDisabled()}
|
||||
, fun{}
|
||||
|
|
|
|||
Loading…
Reference in a new issue