Я вижу как минимум три ошибки в вашем коде.
В произвольном порядке ...
(1) если вы хотите функционал, operator()
должен быть public
; вы делаете они оба private
class d { // default for a class is private, so operator() is private
std::tuple<int, float, std::string&&> operator()() {
return std::tuple<int, float, std::string&&>(-9, 3.14, "olá!");
}
};
class f { // default per a class is private, so operator() is private
bool operator()(int p_i, float p_f, std::string&& p_s) {
std::cout << "i = " << p_i << ", f = " << p_f << ", s = " << p_s
<< std::endl;
return true;
}
};
Вы можете решить эту проблему, сделав operator()
public
или, может быть, проще, сделав d
и f
struct
s.
(2) "olá!"
не является допустимым значением для инициализации std::string &&
std::tuple<int, float, std::string&&>(-9, 3.14, "olá!");
Вы можете скомпилировать с
std::tuple<int, float, std::string&&>(-9, 3.14, std::string{"olá!"});
но это неправильная идея, потому что таким образом вы инициализируете объект ссылкой на объект, который уничтожается сразу после этого, и получаете висящую ссылку внутри кортежа.
Мне не ясно, почему вы хотите использовать std::string &&
в кортеже, но я подозреваю, что вы можете использовать std::string
, а не ссылку на него. Во всем вашем коде, не только в этой функции.
В этом случае следующий код
std::tuple<int, float, std::string>(-9, 3.14, "olá!");
работает.
Если вы действительно хотите ссылку на std::string
в своем кортеже, вы должны передать ссылку на объект с продолжительностью жизни, достаточной для покрытия времени жизни вашего кортежа.
(3) operator()
из d
возвращает std::tuple<int, float, std::string&&>
, где operator()
из f
принимает три параметра: int
, float
и std::string&&
.
Таким образом, вы не можете просто передать значение, возвращаемое от первого ко второму, без распаковки std::tuple
некоторым способом, как вы делаете в a::operator()
bool operator()() { return m_f(m_d()); }
// ........................^^^^^^^^^^ Wrong!
Вы используете C ++ 14, поэтому вы не можете использовать std::apply()
(доступно начиная с C ++ 17)
bool operator()() { return std::apply(m_f, m_d()); }
// ........................^^^^^^^^^^^^^^^^^^^^^^ Starting from C++17
так что эмулировать надо каким-то образом (std::make_index_sequence
, std::index_sequence
, std::get()
и т. Д.).
К примеру
bool operator() ()
{ return call(std::make_index_sequence<sizeof...(t)>{}); }
template <std::size_t ... Is>
auto call (std::index_sequence<Is...> const &)
{
auto tmp { m_d() }; // so m_d() is called only one time
return m_f(static_cast<t>(std::get<Is>(tmp))...);
}
, где call()
может быть private