Я хочу создать вариативную оболочку make_shared<T>
с идеальной переадресацией, но такую, которая SFINAEd в зависимости от того, принимает ли конструктор T
какие-либо неконстантные аргументы ссылки/указателя. Идея состоит в том, чтобы иметь две оболочки, называемые construct
и construct_nonconst
, где при построении Foo(int& r)
или Foo(int* r)
необходимо использовать последнюю. Цель этого состоит в том, чтобы когда разработчики пишут классы, конструкторы которых требуют неконстантных параметров, они могли это сделать, но на месте вызова ясно видно, что конструкция может иметь локальные побочные эффекты.
Я просмотрел Реализация признаков вариативного типа и поиграл с is_constructible
(я пытался преобразовать свои Args ... пакет параметров для всех версий const
), но я не могу понять это.
Желаемый результат:
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
construct_nonconst
. Разве это не намеренно и в этом случае? - person Brian Bi   schedule 06.05.2015const Args&...
, но столкнулся с проблемами с конструкторами, принимающими строки с использованием литералов char. - person experquisite   schedule 06.05.2015is_constructible
, но, похоже, это ничего не дало. Может быть, я неправильно понимаю. Универсальная ссылка с идеальной переадресацией идеальна, я просто хочу отключить ее, если есть какие-либо неконстантные указатели или ссылки (или умные указатели, если на то пошло). - person experquisite   schedule 06.05.2015template<class T> T const& const_if_lvalue(T& t) { return t; } template<class T> T&& const_if_lvalue(T&& t) { return move(t); } template<typename R, typename... Args> R construct(Args&&... args) { return R(const_if_lvalue(forward<Args>(args))...); }
- person dyp   schedule 06.05.2015const_if_lvalue
, согласно stackoverflow.com/questions/7748104/ ,template< class T, typename = typename std::enable_if<!std::is_reference<T>::value>::type > T&& const_if_lvalue(T&& t) { return std::move(t); }
- person experquisite   schedule 06.05.2015template<class T> T const& const_if_lvalue(T const& t) { return t; }
? Важно, чтобы параметр функции былT&
, а неT const&
. Какой компилятор вы использовали? - person dyp   schedule 06.05.2015T& t
, но получил неоднозначные ошибки перегрузки в gcc 4.8.2. - person experquisite   schedule 06.05.2015