【发布时间】:2017-10-17 06:29:44
【问题描述】:
在 C++14 中,您可以执行以下操作:
struct Placeholder
{
template<typename T>
constexpr static T fct(T val) { return val; }
};
int main()
{
constexpr int i{};
auto fct = [](auto&& placeholder) -> decltype(placeholder.fct(i)) { return 5.5f; };
static_assert(fct(Placeholder{}) == 5, "");
}
为了这个例子,考虑一下 Placeholder::fct 实际上是在将输入类型操作为其他东西(在目前的情况下,函数调用是无用的)。
另一方面,在 C++11 中,您可以通过声明模板仿函数来模拟通用 lambda。事实上,我可以简单地将 i 传递给构造函数并将其存储为成员,如下所示:
template<typename T>
class Functor
{
T i;
public:
constexpr Functor(T i) : i{ i } {}
template<typename P>
constexpr auto operator()(P&& placeholder) const -> decltype(placeholder.fct(i))
{
return 5.5f;
}
};
int main()
{
constexpr int i{};
constexpr Functor<decltype(i)> fct(i);
static_assert(fct(Placeholder{}) == 5, "");
}
当我们希望占位符接受可变数量的参数时,问题就出现了,如下所示:
struct Placeholder
{
template<typename... T>
constexpr static auto fct(T... val) -> typename std::common_type<T...>::type
{
return { /* Do something with the values */ };
}
};
事实上,在 C++14 中,我们可以简单地将值直接传递给 lambda:
decltype(placeholder.fct(1, 2, 3))
但是,在 C++11 中,由于我们无法在类中存储可变数量的成员,因此我不知道如何才能获得完全相同的结果。有什么想法吗?
【问题讨论】:
-
我不...明白你的问题是什么。你到底想做什么?您最初的 C++14 示例和 C++11 示例不等效,因此我无法推断问题所在。
-
它们怎么不相等?我在 C++11 中看不到任何其他方法可以达到相同的结果...
-
至于我的用法,我使用带有 SFINAE 的 lambda 来检测 constexpr 输入(显然没有使用 lambda)。它在 C++14 中运行良好,但我试图使其与 C++11 兼容。有关类似用例,请参阅 stackoverflow.com/a/40413051/2950563。
-
lambda 示例没有捕获任何内容。在
Functor示例中(实际上不是functor),它有一个成员变量。无论如何,如果它有一个明确的问题陈述说明您可以在 C++14 中做什么但在 C++11 中遇到困难,它将对您的问题有很大帮助。 -
将
T替换为std::tuple<Ts...>。借助std::index_sequence的 c++11 等效项将元组解包到参数列表中