小编Vit*_*meo的帖子

在`boost :: hana :: map`中更新/替换地图值的典型方法

在一个内部更新值(给定键和新值)的规范方法是boost::hana::map什么?

我尝试使用boost::hana::replace_if但它不起作用,map因为它不是Functor- 我可以通过将其转换map为a tuple然后再转换为a 来实现map它,但听起来效率低下.

我目前正在使用的替代方案是调用map::erase_key后跟map::insert.

是否有任何replaceupdate为此目的而设计的功能可能会丢失?或者这是更新价值的"规范"方式?

c++ boost metaprogramming c++14 boost-hana

5
推荐指数
1
解决办法
711
查看次数

检测可调用对象是否为二进制(包括通用约束lambda)

我正在尝试检测可调用对象是否为二进制(即,它是否operator()采用两个参数).我想对lambdas执行此检查,包括泛型lambdas约束泛型lambda (例如,使用尾随std::enable_if_t返回类型).


注意:不是"普通lambda的arity"的副本.我只关心检查泛型lambda是否是二进制的,并且我已经可以为不受约束的泛型lambda不使用其体中的参数的泛型lambda做到这一点.


我目前的方法是应用Kris Jusiak的Boost.DI C++ Now 2015谈话中描述的技术之一:any_type.它基本上是一个可以隐式转换为任何其他类的类.

struct any_type
{
    template <typename T>
    constexpr operator T() const noexcept
    {
        return {};
    }
};
Run Code Online (Sandbox Code Playgroud)

在定义之后any_type,我正在使用检测习惯来检查是否可以使用两个参数调用特定的可调用对象:

template<class T>
using is_binary_callable_impl = decltype(std::declval<T>()(any_type{}, any_type{}));

template <typename T>
using is_binary_callable = std::experimental::is_detected<is_binary_callable_impl, T>;
Run Code Online (Sandbox Code Playgroud)

这种方法适用于非泛型和通用lambda ...

auto unary_nongeneric = [](int){};
auto unary_generic = [](auto){};
auto binary_nongeneric …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++14 detection-idiom c++17

5
推荐指数
0
解决办法
80
查看次数

在`static_assert`,`if constexpr(...)`和`constexpr`变量之间的模板中对`constexpr` lambdas的评估不一致

(使用g++ 7.0trunk.)

鉴于以下"类型到价值包装"实用程序......

template <typename T>
struct type_wrapper { using type = T; };

// "Wraps" a type into a `constexpr` value.
template <typename T>
constexpr type_wrapper<T> type_c{};
Run Code Online (Sandbox Code Playgroud)

...我创建了以下函数来检查表达式的有效性:

template <typename TF>
constexpr auto is_valid(TF)
{
    return [](auto... ts) constexpr 
    {
        return std::is_callable<TF(typename decltype(ts)::type...)>{};
    };
}   
Run Code Online (Sandbox Code Playgroud)

is_valid功能可以使用如下:

// Evaluates to `true` if `some_A.hello()` is a valid expression.
constexpr auto can_add_int_and_float = 
    is_valid([](auto _0) constexpr -> decltype(_0.hello()){})
        (type_c<A>);

// Evaluates to `true` if `some_int + some_float` is …
Run Code Online (Sandbox Code Playgroud)

c++ lambda constant-expression constexpr c++17

5
推荐指数
1
解决办法
255
查看次数

将 `std::move(*this)` 放入从 `this-&gt;some_method` 创建的对象中是否安全?

我正在尝试构建一系列可调用对象,以便稍后异步执行。我想尝试以下方法:构建节点的“嵌套”结构(通过将每个节点移动到其“父节点”中),从而生成一个存储所有计算并可以按需启动链的对象。

这就是我的想法:

template <typename TParent, typename TF>
struct node
{
    TParent _parent;
    TF _f;

    node(TParent&& parent, TF&& f) 
        : _parent{std::move(parent)}, _f{std::move(f)}
    {
    }

    template <typename TFContinuation>
    auto then(TFContinuation&& f_continuation)
    {
        using this_type = node<TParent, TF>;
        return node<this_type, std::decay_t<TFContinuation>>
            {std::move(*this), std::move(f_continuation)};
//           ^^^^^^^^^^^^^^^^
//           ...safe?
    }   
};
Run Code Online (Sandbox Code Playgroud)

上面的代码允许用户编写如下所示的链:

int main()
{
    node n{some_root_callable, []{/*...*/}};
    n.then([]{/*...*/})
     .then([]{/*...*/})
     .then([]{/*...*/})
     .then([]{/*...*/});
}
Run Code Online (Sandbox Code Playgroud)

(真正的实现将支持更有用的抽象,例如when_all(...)when_any(...)。)

魔盒示例


假设TParentTF、 和TFContinuation是可移动的可调用对象,那么在 的调用期间调用是否安全(即明确定义) …

c++ move-semantics c++11

5
推荐指数
1
解决办法
1220
查看次数

模板参数类型从类定义中扣除

是否可以在一个成员函数的定义中为类使用类模板参数推导?...或者我被迫在C++ 03中编写我的助手类?CCmake_c

考虑这种最小化和简化的场景,它构建了一系列任意函数对象:

template <typename F>
struct node;

template <typename FFwd>
node(FFwd&&) -> node<std::decay_t<FFwd>>;
Run Code Online (Sandbox Code Playgroud)

node类存储它通过完美转发初始化函数对象.我需要一个演绎指南,指向decay函数对象的类型.

template <typename F>
struct node
{
    F _f;

    template <typename FFwd>
    node(FFwd&& f) : _f{std::forward<FFwd>(f)}
    {
    }

    template <typename FThen>
    auto then(FThen&& f_then)
    {
        return node{[f_then = std::move(f_then)]
                    { 
                        return f_then(); 
                    }};
    }
};
Run Code Online (Sandbox Code Playgroud)

然后,我定义了node构造函数和一个.then返回一个新节点的continuation成员函数(它的实现是无意义的,以最小化示例的大小).如果我试图调用.then......

auto f = node{[]{ return 0; }}.then([]{ return 0; });
Run Code Online (Sandbox Code Playgroud)

...我收到一个意外的编译错误: …

c++ templates template-argument-deduction c++17

5
推荐指数
1
解决办法
325
查看次数

加密模板模板参数错误

我正在尝试创建一个从a std::map或an 获取键的函数std::unordered_map。我可以使用简单的重载,但首先我想知道这段代码有什么问题。

template<typename K, typename V, template<typename, typename> class TContainer>  
std::vector<K> getKeys(const TContainer<K, V>& mMap)
{
    std::vector<K> result;
    for(const auto& itr(std::begin(mMap)); itr != std::end(mMap); ++itr) result.push_back(itr->first);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

当使用调用它时std::unordered_map,即使手动指定所有模板类型名称,clang ++ 3.4 也会说:

template template参数的模板参数与其对应的模板template参数不同。

c++ templates types typename c++11

4
推荐指数
1
解决办法
1145
查看次数

高效优雅地返回emplaced unique_ptr

我发现(感谢StackOverflow注释)我的代码中存在安全漏洞:

std::vector<std::unique_ptr<Item>> items;

template<class... TS> Item& create(TS&&... mArgs)
{
    auto item(new Item(std::forward<TS>(mArgs)...);
    items.emplace_back(item); // Possible exception and memory leak
    return *item;
}
Run Code Online (Sandbox Code Playgroud)

基本上,如果抛出Item,使用raw 分配new可能会泄漏内存emplace_back.

解决方案永远不会使用raw new,而是std::unique_ptr在方法体中使用right.

std::vector<std::unique_ptr<Item>> items;

template<class... TS> Item& create(TS&&... mArgs)
{
    auto item(std::make_unique<Item>(std::forward<TS>(mArgs)...);
    items.emplace_back(std::move(item));
    return *item; // `item` was moved, this is invalid!
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,返回item是无效的,因为我不得不item使用std::move它来将它放入items容器中.

我想不出一个需要item在另一个变量中存储地址的解决方案.然而,原始(错误)解决方案非常简洁易读.

是否有更优雅的方式返回std::unique_ptr被移动到容器中的位置?

c++ return unique-ptr c++11 emplace

4
推荐指数
1
解决办法
683
查看次数

避免使用`operator <<`推迟"子"对象构造

假设我有一个容器对象来存储std::vector多态子.

struct Child
{
    Child(Parent& mParent) { /* ... */ }
    virtual ~Child() { }
};

class Parent
{
    private:
        std::vector<std::unique_ptr<Child>> children;

        template<typename T, typename... TArgs> 
        auto& mkChild(TArgs&&... mArgs)
        {
            // `static_assert` that `T` is derived from `Child`...
            children.emplace_back(std::make_unique<T>(std::forward<TArgs>(mArgs)...));
            return *children.back();
        }

    public:
        template<typename T, typename... TArgs> 
        auto& add(TArgs&&... mArgs)
        {
            mkChild<T>(std::forward<TArgs>(mArgs)...));
            return *this;
        }
};
Run Code Online (Sandbox Code Playgroud)

现在我可以使用这样的Parent类:

int main()
{
    Parent p;
    p.add<Child1>(some_args1).add<Child2>(some_args2);
}
Run Code Online (Sandbox Code Playgroud)

虽然这种语法实现了我想做的事情(将子项添加到单个父项中),但我觉得很难阅读,特别是在我的实际用例中.

我真的很想用operator<<.但我无法想出一种方法来构建孩子.

// Desired syntax
int main()
{
    Parent p; …
Run Code Online (Sandbox Code Playgroud)

c++ constructor operator-overloading variadic-templates c++14

4
推荐指数
1
解决办法
82
查看次数

将两个整数的序列匹配到`std :: pair <int,int>`

我正在尝试使用Boost.Sprit x3将两个整数的序列匹配成一个std::pair<int, int>.根据文档判断,以下代码应该编译:


#include <string>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>

int main()
{
    using namespace boost::spirit::x3;

    std::string input("1 2");
    std::pair<int, int> result;
    parse(input.begin(), input.end(), int_ >> int_, result);
}
Run Code Online (Sandbox Code Playgroud)

melpon.org链接


但是,它只匹配第一个整数.如果我改变std::pair<int, int> result;int result;,然后打印result,我得到1我的输出.

为什么会这样?这不是int_ >> int_定义匹配(并设置为属性)两个整数的解析器的正确方法吗?

c++ boost-fusion c++14 boost-spirit-x3

4
推荐指数
1
解决办法
150
查看次数

允许针对不同版本的源代码进行互操作的确切机制是什么?

我了解 Editions 的目标以及如何使用它们,但文档并没有说明它们的内部工作原理。

假设我有两个源文件:

  • old.rs,针对 Rust 2015;

  • new.rs,针对 Rust 2018。

我想构建一个同时使用它们的应用程序。正在使用什么机制来确保它们可以互操作?

两者都做old.rs,并new.rs会转换为相同型号HIR?或者均质化发生在此之前(例如 AST 水平)还是之后(例如 MIR 水平)?

rust

4
推荐指数
1
解决办法
265
查看次数