【发布时间】:2015-05-22 13:11:03
【问题描述】:
我正在尝试编写一个宏,当只需要单个 return 语句时,它会缩短 lambda 表达式语法。我的第一次尝试是这样的:
struct void_t{};
#define LR(EXPR) (auto&& p_1 = void_t{}, auto&& p_2 = void_t{}, auto&& p_3 = void_t{}){ return EXPR; }
不幸的是,它没有像我预期的那样工作。默认参数基本上被忽略,我不能用少于三个参数调用这个 lambda:
std::cout << []LR(p_1)("test"); // compile error
std::cout << []LR(p_1 + p_2)(2, 3); // compile error
std::cout << []LR(p_1 + p_2)(std::string("hello "), std::string(" world!")); // compile error
std::cout << []LR(p_1 + p_2)(2, 3, 0); // OK
我设法设计了一些看似可行但存在问题的复杂解决方法:
template<class LT> struct lambda_wrapper
{
lambda_wrapper(LT p_lambda): m_lambda(p_lambda){}
template<class T1, class T2, class T3>
auto operator()(T1&& p_1, T2&& p_2, T3&& p_3) const
{
return m_lambda(std::forward<T1>(p_1),
std::forward<T2>(p_2),
std::forward<T3>(p_3));
}
template<class T1, class T2> auto operator()(T1&& p_1, T2&& p_2) const
{
return m_lambda(std::forward<T1>(p_1), std::forward<T2>(p_2), void_t{});
}
template<class T1> auto operator()(T1&& p_1) const
{
return m_lambda(std::forward<T1>(p_1), void_t{}, void_t{});
}
auto operator()() const
{
return m_lambda(void_t{}, void_t{}, void_t{});
}
private:
LT m_lambda;
};
template <class LT> lambda_wrapper<LT> operator++(LT&& p_lambda, int)
{
return {std::forward<LT>(p_lambda)};
}
#define LR(EXPR) (auto&& p_1, auto&& p_2, auto&& p_3){ return EXPR; }++
谁有更好的主意?
【问题讨论】:
-
您可以使用返回
std::function的函数模板。或者您可以使用可变参数宏(您可以让它计算其参数并调用特定于该参数数量的宏)。 -
1) 我不确定这个模板函数会是什么样子? 2)我的宏只有一个参数
-
不知道您的
lamda_wrapper与您的问题有什么关系。您的LR宏看起来和以前一样。 -
lambda_wrapper 使表达式
[]LR(p_1)("test");进行编译。你可能会忽略我使用的后期增量技巧。 -
你可以使用 LR1, LR2, LR3, ... 它仍然会缩短行数,不像单个 LR 宏那样优雅,但它可以工作。