如果我想使用可变参数模板有一个默认参数,以下内容是完全有效的。我想知道类似的东西是否可以在班级中复制:
inline static constexpr auto myrun_func = [](auto b){std::cout<<b<<std::endl;};
template<class UnaryFunction, class... Args>
struct running_func{
public:
running_func(UnaryFunction&& unary, Args... args, const char* str = __builtin_FUNCTION()){
std::cout<<"function was run from "<<str<<std::endl;
std::forward<UnaryFunction>(unary)(args...);
}
};
template<class UnaryFunction, class... Args>
running_func(UnaryFunction&& unary, Args... args) -> running_func<UnaryFunction, Args...>;
void test(){
running_func(myrun_func, 10);
}
所以输出将是:
function was run from test()
10
我想知道我是否可以在这样的课堂上做类似的事情:
inline static constexpr auto myrun_func = [](auto b){std::cout<<b<<std::endl;};
class foo{
template<class UnaryFunction, class... Args>
struct running_func{
running_func(foo* ex, UnaryFunction&& unary, Args... args, const char* str = __builtin_FUNCTION()){
std::cout<<"function was run from "<<str<<std::endl;
std::forward<UnaryFunction>(unary)(args...);
ex->f();
}
};
template<class UnaryFunction, class... Args>
running_func(this, UnaryFunction&& unary, Args... args) -> running_func<UnaryFunction, Args...>;
void f(){
std::cout<<"f() called"<<std::endl;
}
};
void test(){
foo example;
example.running_func(myrun_func, 10);
}
以下显然行不通。但是,我想知道是否可以在
running_func
结构可以访问该类的地方使用类似的东西。
您的示例格式错误,您无法作为成员访问类型(尽管有建议),并且
this
不能在绑定函数上下文之外使用。如果您愿意稍微改变一下访问方法,您可以执行以下操作:
inline constexpr auto runnable = [](auto b) { std::cout << b << std::endl; };
/* `$' is a nonstandard identifier but I like how it looks :P */
template <typename...TT> struct $ : std::tuple<TT...> { };
template <typename...TT> $(TT&&...) -> $<TT...>;
struct Foo {
void f() { std::cout << "f() called" << std::endl; }
template <typename F, typename...TT>
void running_func(F&& fn, $<TT...> tup,
const std::source_location& sl = std::source_location::current()) {
std::cout << "function was run from `" << sl.function_name() << "'\n";
std::apply(std::forward<F>(fn), static_cast<std::tuple<TT...>&>(tup));
this->f();
}
};
void test(){
Foo foo {};
foo.running_func(runnable, ${ 10 });
}
当然你也可以将其设为宏,但这会降低可读性:
inline constexpr auto runnable = [](auto b) { std::cout << b << std::endl; };
#define CALLER_FUNC your_name_here
#define running_func(...) CALLER_FUNC(std::source_location::current(), __VA_ARGS__)
struct Foo {
void f() { std::cout << "f() called" << std::endl; }
template <typename F, typename...TT>
void CALLER_FUNC(const std::source_location& sl, F&& fn, TT&&...tt) {
std::cout << "function was run from `" << sl.function_name() << "'\n";
std::forward<F>(fn)(std::forward<TT>(tt)...);
this->f();
}
};
void test(){
Foo foo {};
foo.running_func(runnable, 10);
}