SFINAE enable_if for variadic perfect forwarding t

2019-07-18 14:01发布

问题:

I want to create a variadic perfect-forwarding make_shared<T> wrapper, but one which is SFINAEd on whether the constructor of T takes any non-const reference/pointer arguments. The idea is to have two wrappers, called construct and construct_nonconst, where when constructing a Foo(int& r) or Foo(int* r), one is obliged to use the latter. The purpose of this is so that when developers write classes whose constructors require non-const parameters, they can do so, but it clearly shows up at the call site that the construction may have local side-effects.

I looked at Implementing variadic type traits, and played with is_constructible (I was trying to convert my Args... parameter pack to all the const versions therein), but I can't quite seem to figure it out.

Desired outcome:

struct NonConst
{
  NonConst(int& uhOh)
  {
    uhOh = 2;
  }
};

struct Const
{
  Const(const int& noProblemo)
  {
    // ...
  }
};

struct ByValueStr
{
  ByValueStr(std::string noProblemo)
  {
    // ...
  }
};

int x = 5;
const int y = 5;
std::string s("foo")

auto nc1 = builder<NonConst>::construct(x); // this doesn't compile
auto nc2 = builder<NonConst>::construct_nonconst(x); // fine, but noticeable
auto c1 = builder<Const>::construct(x); // fine
auto c2 = builder<ByValueStr>::construct(s); // fine