У меня есть шаблон Foo, которому принадлежит T, и я бы хотел, чтобы у него был конструктор Variadic, который переводит свои аргументы в конструктор T:
template<typename T>
struct Foo {
Foo()
: t() {}
Foo(const Foo& other)
: t(other.t) {}
template<typename ...Args>
Foo(Args&&... args)
: t(std::forward<Args>(args)...) {}
T t;
};
Однако это не позволяет скопировать Foo:
int main(int argc, char* argv[]) {
Foo<std::shared_ptr<int>> x(new int(42));
decltype(x) copy_of_x(x); // FAILS TO COMPILE
return EXIT_SUCCESS;
}
потому что, согласно этот ответ, неконстантность аргумента приводит к тому, что конструктор Variadic лучше сочетается. Я не хочу принуждать своих абонентов использовать const_cast по понятным причинам.
Одним из возможных решений, которое я нашел, было написать "конструктор копирования" для Foo, который принимает неконстантный Foo и использует переадресацию конструктора:
Foo(Foo& other)
: Foo(const_cast<const Foo&>(other)) {}
Когда этот конструктор определен, все работает снова: теперь предпочтительна копия аргумента non-const Foo. Однако это кажется очень отрывочным для меня, поскольку это "лечение" кажется хуже, чем болезнь.
Есть ли другой способ достижения этого эффекта, чтобы указать, что конструктор естественных копий должен быть предпочтительнее конструктора переменных? Если нет, есть ли какие-либо неблагоприятные последствия для определения этого конструктора копии неконстантного аргумента?