Дан код на С++17:
template<class T>
struct Ok {
T value;
};
template<> struct Ok<void> {};
// template deduction guides
template<class T> Ok(T) -> Ok<T>;
Template deduction guides позволяют имея тип Ok<T> вызывать Ok как функцию (так выглядит, на самом деле вызывается конструктор):
auto c = Ok(5); // T deduced as int
// без template deduction guide я так писать не могу,
// но должен писать:
auto c = Ok<int>(5); // T can not be deduced :(
Вопрос в том, как это переписать на С++14 или ниже? Чтоб я писал просто:
auto c = Ok("hello"s); // T deduced as std::string
Но с произвольным типом.
template<class T>
Ok<std::decay_t<T>> makeOk(T&& arg){
return Ok<std::decay_t<T>>{std::forward<T>(arg)};
}
auto c = makeOk(5);
auto d = makeOk(std::make_unique<double>(6.7));
Начал писать как комментарий, но не уложился в границы.
Ответ уже дан, но по большому счёту он был у Вас в вопросе, когда сравнивали конструктор с функцией.
Классическое решение - это как раз использование шаблонных make- функций. Всякие make_pair, make_unique, make_shared яркие тому примеры.
Дополнительно хочу заметить, что если тип Ok явно указывается только при создании (через функцию-конструктор), то можно зайти немного с другого конца, нежели это сделал Виктор Смирнов в своём ответе, и в качестве имени порождающей функции использовать Ok вместо makeOk. А саму структуру переименовать, скажем, в Ok_. Может быть таким образом получится уменьшить количество мест, требующих изменения кода.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей