Не совсем ясно, что вы надеетесь достичь в отношении референсного члена rvalue.Это просто не выглядит правильно.Вы должны избегать хранения ссылки.Вы по-прежнему можете использовать такие вещи, как std :: ref и std :: cref, если вы хотите, чтобы объект функции сохранял объект, похожий на ссылку (очень похоже на поведение std :: bind).
Проблема, с которой вы столкнулись, заключается вчто нельзя инициализировать ссылку на rvalue значением lvalue целевого типа.Но вы пытаетесь сделать это, потому что параметр конструктора "arg" является с именем rvalue, что делает его lvalue выражением в списке инициализатора.Вы, вероятно, использовали старую версию GCC для компиляции этого кода.Более новые версии также будут жаловаться на это.
Вы можете избавить себя от некоторых проблем, полагаясь на std :: bind:
template<class FuncType>
class F : public B {
public:
explicit F(FuncType func)
: f(std::forward<FuncType>(func))
{}
void execute() { f(); }
private:
FuncType f;
};
....
auto fun = std::bind(myFunction,text2.c_str());
B* ptr = new F<decltype(fun)>(fun);
Если вы действительно хотите разобраться с привязкой параметров самостоятельно, выдолжен сделать это так:
template<class FuncType, class ParamType>
class F : public B {
public:
F(FuncType func, ParamType para)
: f(std::forward<FuncType>(func))
, p(std::forward<ParamType>(para))
void execute() { f(p); }
private:
FuncType f;
ParamType p;
};
Имейте в виду, что тип параметра T &&, где T может быть выведен, имеет особое значение.Это универсальный параметр.Вывод аргумента шаблона сделает T ссылкой lvalue (и T && также по правилам свертывания ссылок) в случае, если аргумент был lvalue.Поэтому, если вы всегда хотите, чтобы параметр был сохранен как копия, вы должны написать
template<class FuncType, class ArgType>
B * registerFunc(FuncType func, ArgType && arg)
{
typedef typename std::decay<ArgType>::type datype;
return new F<FuncType,datype>(func, std::forward<ArgType>(arg));
}
Я бы предпочел функцию registerFunc, подобную этой.По умолчанию он копирует объект функции и объект параметра.Переопределить это можно через std :: ref и std :: cref:
registerFunc(some_func,std::cref(some_obj));