我有一个类似容器的类,其方法与std::apply. 我想使用const限定符重载此方法,但是当我尝试使用通用 lambda 调用此方法时,我从std::invoke_result_t. 我std::invoke_result_t用来推断方法的返回值以及对参数执行 SFINAE 检查。
#include <type_traits>
#include <utility>
template <typename T>
class Container
{
public:
template <typename F>
std::invoke_result_t<F, T &> apply(F &&f)
{
T dummyValue;
return std::forward<F>(f)(dummyValue);
}
template <typename F>
std::invoke_result_t<F, const T &> apply(F &&f) const
{
const T dummyValue;
return std::forward<F>(f)(dummyValue);
}
};
int main()
{
Container<int> c;
c.apply([](auto &&value) {
++value;
});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用 Clang 6.0 编译时的错误消息:
main.cc:27:9: error: cannot assign to …Run Code Online (Sandbox Code Playgroud) 请看下面的代码
#include <iostream>
#include <functional>
#include <string>
int main()
{
std::function<void(std::string&)> theFunc;
std::string foo = "0";
theFunc = [](std::string a) { a = "1"; }; // this compiles but has a different function signature
theFunc(foo);
std::cout << "foo should be 1 but is " << foo << std::endl;
theFunc = [](auto a) { a = "2"; }; // this infers the wrong type for auto(by val not by ref), creates the wrong function signature and compiles
theFunc(foo);
std::cout << "foo …Run Code Online (Sandbox Code Playgroud) 我有一个带有命名 lambda 的头文件,用于测量某些函数的执行时间(该 lambda 部分是这个问题的结果How to Write a Lambda Wrapping a Function with Optional Return Value)。它驻留在我从几个翻译单元中包含的头文件中。这在 g++ 8 和 g++ 9 中运行良好。现在当我切换到 g++ 10.1 时,链接时出现错误。
请检查以下简化示例。
以下是 Wandbox 中的示例:https ://wandbox.org/permlink/Sizb6txrkW5dkJwT 。
文件“Lambda.h”:
#pragma once
#include <string>
auto measure = [](bool enabled, const std::string& taskName, auto&& function,
auto&&... parameters) -> decltype(auto)
{
return std::forward<decltype(function)>(function)(
std::forward<decltype(parameters)>(parameters)...);
};
Run Code Online (Sandbox Code Playgroud)
文件“Test1.cpp”:
#include "Lambda.h"
Run Code Online (Sandbox Code Playgroud)
文件“Test2.cpp”:
#include "Lambda.h"
Run Code Online (Sandbox Code Playgroud)
然后我像这样构建:
g++ -c Test1.cpp
g++ -c Test2.cpp
g++ -shared -o Test.dll Test1.o Test2.o
Run Code Online (Sandbox Code Playgroud)
一切正常,直到 g++ 9.2,但使用 …
我有以下C ++代码:
template <class T1, class T2, class T3>
void MetaTypeHandler(T1 lambda1, T2 lambda2, T3 lambda3) {
lambda1(1);
lambda2('x');
lambda3(true);
}
int main() {
auto f = [] (auto x) {};
MetaTypeHandler(f,f,f);
}
Run Code Online (Sandbox Code Playgroud)
经过f多次是丑陋的。是否有可能写MetaTypeHandler(),这样f传递只有1〜2次?我认为模板模板参数可能会有所帮助,但无法绕过它们。
一个快速的谷歌搜索会告诉你尽可能避免使用async void myMethod()方法。在许多情况下,有办法使之成为可能。我的问题基本上是这个最佳实践的一个分支:
下面的 lambda 表达式的计算结果是什么?
Task.Run( async ()=> await Task.Delay(1000));
Run Code Online (Sandbox Code Playgroud)
如果它变成了,async Task那么我们将遵循最佳实践。
但是如果它评估为async void呢?
请考虑以下示例:
template <typename lambda> void call_me_back(const lambda & callback)
{
// Very complicated calculation to find the meaning of everything
callback(42);
}
int main()
{
call_me_back([](const int & value)
{
std :: cout << value << std :: endl;
});
}
Run Code Online (Sandbox Code Playgroud)
在这里,我提供call_me_back了一个接受一个的lambda int.经过一些长时间的计算后call_me_back调用callback,并callback打印出来.像蛋糕一样容易.
现在,根据执行情况,call_me_back需要callback使用int或使用其他类型调用.我们可以编辑前面的例子
template <typename lambda> void call_me_back(const lambda & callback)
{
// Very complicated calculation to find the meaning of everything
if(rand() …Run Code Online (Sandbox Code Playgroud) 我有一个Derived继承自类的类Base<ResourceType>:
template <class ResourceType>
class Base {
protected:
ResourceType* resource;
public:
void set_resource(ResourceType* resource) {
this->resource = resource;
}
};
template <class ResourceType>
class Derived : public Base<ResourceType> {
public:
using Base<ResourceType>::resource;
void print () {
std::cout << *resource << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
我想创建一个创建类型对象的工厂Derived.我当然可以用功能做到这一点:
template <typename ResourceType>
auto derived_factory () {
return new Derived<ResourceType>();
}
auto derived = *(derived_factory<int>());
Run Code Online (Sandbox Code Playgroud)
但是,我无法为工厂编写lambda函数.如果我使用auto关键字接受模板参数,我可以编写模板化的lambda函数,但在这里我只想使用模板来确定返回类型.以下失败:
auto derived_factory = []<typename ResourceType>() {
return new Derived<ResourceType>();
};
auto derived = *(derived_factory<int>()); …Run Code Online (Sandbox Code Playgroud) 假设你有一个带有a的可变类std::tuple,可以使用args + 1 new arg构造.当使用std::apply()和原始花括号构造函数构造时,该构造函数不返回rvalue.这意味着班级不是移动构造的.下面举一个例子来澄清.
#include <cstdio>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <vector>
template <class... Args>
struct icecream {
icecream() = default;
template <class... MoreArgs>
icecream(icecream<MoreArgs...>&& ice) {
std::apply(
[this](auto&&... ds) {
data = { std::move(ds)..., {} };
},
std::move(ice.data));
}
// This works :
// template <class... MoreArgs>
// icecream(icecream<MoreArgs...>&& ice) {
// std::apply(
// [this](auto&&... ds) {
// data = { std::move(ds)...,
// std::move(std::vector<double>{}) };
// },
// std::move(ice.data));
// }
std::tuple<std::vector<Args>...> …Run Code Online (Sandbox Code Playgroud) 我有一个容器类模板,其中包含几种不同类型的成员。我想传递一个用于每个元素的函子。我可以用以下代码做我想做的事情:
#include <iostream>
template <typename T1, typename T2>
class MyContainer
{
public:
template <typename Op>
void run_operation(Op op)
{
op(t1);
op(t2);
}
T1 t1;
T2 t2;
};
struct OutputOperation
{
template <typename T>
void operator()(T t)
{
std::cout << "value is " << t << std::endl;
}
};
int main() {
MyContainer<int, double> container;
OutputOperation out_op;
container.run_operation(out_op);
}
Run Code Online (Sandbox Code Playgroud)
当使用模板定义结构时operator(),我缺少定义lambda函数时的舒适性。有什么方法可以使用lambda函数达到与struct相同的效果吗?还是至少可以让我在调用方法中定义操作(某些模板无法做到)?
#include <iostream>
#include <tuple>
#include <iostream>
#include <utility>
template <std::size_t... Idx>
auto make_index_dispatcher(std::index_sequence<Idx...>)
{
return [](auto&& f) { (f(std::integral_constant<std::size_t, Idx>{}), ...); };
}
template <std::size_t N>
auto make_index_dispatcher()
{
return make_index_dispatcher(std::make_index_sequence<N>{});
}
template <typename Tuple, typename Func>
void for_each(Tuple&& t, Func&& f)
{
constexpr auto n = std::tuple_size<std::decay_t<Tuple>>::value;
auto dispatcher = make_index_dispatcher<n>();
dispatcher([&f, &t](auto idx) { f(std::get<idx>(std::forward<Tuple>(t))); });
}
int main()
{
for_each(std::make_tuple(1, 42.1, "hi"), [](auto&& e) {std::cout << e << ","; });
}
Run Code Online (Sandbox Code Playgroud)
问题1>为什么在下面的语句中我必须使用std::integral_constant<std::size_t, Idx>{}而不是简单地使用Idx …
c++ template-meta-programming variadic-templates generic-lambda c++17