标签: c++17

是否有可能创建更好的`std :: min`和`std :: max`版本?

随着C++ 17的新特性,是有可能创造一个更好的std::minstd::max

我的意思更好:

  • std::min/max悬挂引用的问题.
  • std::min/max不适用于不同类型(即min(short, int)需要明确指定类型min<int>(...))

我希望有一个更好的实现,其中:

  • 避免悬空引用问题(例如,min(a, 4); 正常工作)
  • 适用于不同类型(例如,min((short)4, (int)8);编译)
  • 避免不必要的对象副本(例如,如果我有一个代表一个大整数的类,它只在不可避免时复制它)

是否可以这样做,或者是std::min/max目前最好的解决方案?

c++ c++17

0
推荐指数
1
解决办法
186
查看次数

如何从函数返回std :: optional <myclass>?

我似乎错过了一些非常简单的事情.以下不起作用:

#include <optional>

class Alpha {
    Alpha() { }
    Alpha(const Alpha& that) { }
    Alpha(Alpha&& that) { }
    ~Alpha() { }

    static std::optional<Alpha> go() {
        return Alpha();
    }
};
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

no suitable user-defined conversion from "Alpha" to "std::optional<Alpha>" exists 
T in optional<T> must satisfy the requirements of Destructible 
'return': cannot convert from 'Alpha' to 'std::optional<Alpha>'
Run Code Online (Sandbox Code Playgroud)

我错过了什么,你能解释一下原因吗?

c++ optional c++17

0
推荐指数
1
解决办法
329
查看次数

fold表达式:右移初始化行为

我很乐意使用折叠表达式来更好地理解我可以在项目中使用它们的位置.所以我选择用简单的方式初始化它们

(datas = ... = 1);
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都按预期工作,每个值都是1.然后我尝试使用左移初始化,所以:

    (datas = ... = 1);
    (datas <<= ...);
Run Code Online (Sandbox Code Playgroud)

这也是我期望的工作,它增加2的力量它很好.最后我尝试了这个:

(datas = ... = 1);
(datas >>= ...);
Run Code Online (Sandbox Code Playgroud)

并且它给我输出a 0, 1, 0, 1, 0, 1, ...,我预计它将全部为0.所以这里的代码:

#include <iostream>

template<typename... T>
void test(T&&... datas) {
    (datas = ... = 1);
    (datas >>= ...);
    (std::cout << ... << (std::to_string(datas) + " ")) << std::endl;
}

int main(int argc, char const *argv[])
{
    int v1, v2, v3, v4;
    test(v1, v2, v3, v4);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么它是 …

c++ fold-expression c++17

0
推荐指数
1
解决办法
44
查看次数

使函数只取现在每对中的第一个值

我需要使一个函数只取每个std::pair传递给它的参数的第一个值.传递的非类型值std::pair将不加改变地使用.我的以下解决方案仅适用于带有两个参数的函数.我需要知道如何将它推广到传递的任意数量的参数.

#include <type_traits>

template <typename T, typename = void>
struct has_first_type : std::false_type { };

template <typename T>
struct has_first_type<T, std::void_t<typename T::first_type>> : std::true_type { };

template <typename R, typename T, typename U, typename = void> struct act_on_first;

template <typename R, typename T, typename U>
struct act_on_first<R, T, U, std::enable_if_t<has_first_type<T>::value && has_first_type<U>::value>> {
    template <typename F>
    static R execute (const T& t, const U& u, F f) {
        return f(t.first, u.first);
    }
};

template <typename R, …
Run Code Online (Sandbox Code Playgroud)

c++ function template-meta-programming variadic-templates c++17

0
推荐指数
1
解决办法
62
查看次数

获取std :: variant的基础类型

快速提问:

是否有可能获得std::variant运行时使用的基础类型?

我的第一个猜测是使用decltype()这样的:

    std::variant<int, float> v;
    v = 12;
    std::vector<decltype(v)> vec;
Run Code Online (Sandbox Code Playgroud)

但我的向量的声明类型std::vector<std::variant<int, float>>不是std::vector<int>.

知道如何实现这一目标吗?:)

c++ variant c++17

0
推荐指数
1
解决办法
197
查看次数

无法通过std :: ref()调用带有auto&parameter的std :: invoke()

我正在尝试创建一个Invoker对象,该对象为该仿函数存储仿函数和一组参数 - 全部按值(用于线程). Invoker::operator()()将使用复制的参数调用存储的仿函数.

到目前为止,一切都工作正常,直到尝试通过auto&使用传递参数std::ref(variable).具体来说,此代码应该可以工作,但它不会使用给定的错误消息进行编译:

int var = 0;
Invoker{
    [](auto& r) {
        printf("%d\n", r);
    }, std::ref(var)
}();
Run Code Online (Sandbox Code Playgroud)

我希望它std::thread与这个例子的工作方式类似.错误消息是:

test.cpp:65:14: error: no matching function for call to ‘invoke(std::__tuple_element_t<0, std::tuple<main()::<lambda(auto:1&)>, std::reference_wrapper<int> > >, std::__tuple_element_t<1, std::tuple<main()::<lambda(auto:1&)>, std::reference_wrapper<int> > >)’
   std::invoke(std::get<Indicies>(std::move(args))...);
   ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我目前的Invoker课程:

template<typename... Args>
struct Invoker {
    std::tuple<std::decay_t<Args>...> args;

    explicit Invoker(Args... args)
        : args(std::forward<Args>(args)...)
    { }

    template<size_t... Indices>
    void _Invoke(std::index_sequence<Indices...>) {
        std::invoke(std::get<Indices>(std::move(args))...);
    }

    void operator()() {
        _Invoke(std::make_index_sequence<std::tuple_size_v<decltype(args)>>{});
    }
};

/* Invoker …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11 c++17

0
推荐指数
1
解决办法
226
查看次数

为什么std :: nullopt_t是C++标准的一部分?

我不明白在标准中包含std :: nullopt_t的原因.它是否仅为方便起见而存在,还是在某些利基环境中需要?

为了清楚起见,我理解它被用作构造空std :: optional对象的参数.但是考虑到std :: optional的默认构造函数已经存在,似乎没有明显的动机存在std :: nullopt_t.对于std :: optional,是否必须存在这样的构造函数和赋值运算符以符合特定的概念?如果是这样,哪个概念?

c++ c++17

0
推荐指数
1
解决办法
410
查看次数

C++析构函数通过引用

我想与你分享一个我无法解决的小问题,这里是代码(仅供测试):

#include <windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <utility>
#include <type_traits>
#include <sstream>

struct Procedure {
    Procedure(HANDLE)
    { std::cout << "ctor w/connection: " << this << std::endl; }

    ~Procedure()
    { std::cout << "dtor: " << this << std::endl; }

    Procedure(Procedure &&rhs) {
        std::cout << "ctor w/move: " << this << std::endl;
        this->m_Params = std::move(rhs.m_Params);
    }

    Procedure& operator= (Procedure &&rhs) {
        std::cout << "operator= w/move: " << this << std::endl;
        if (this != &rhs) this->m_Params = std::move(rhs.m_Params);
        return *this; …
Run Code Online (Sandbox Code Playgroud)

c++ move move-semantics c++17

0
推荐指数
1
解决办法
70
查看次数

为什么在定义析构函数时隐式删除​​了移动构造函数

我想知道为什么委员会决定在定义析构函数时隐式删除​​移动构造函数.

#include <iostream>
#include <vector>
#include <memory>

struct A { 
  ~A(){}; 
  std::unique_ptr<int> a;
};


int main()
{
    A a;
    A b = std::move(a);
}
Run Code Online (Sandbox Code Playgroud)

http://coliru.stacked-crooked.com/a/c0c067fc51260794

有没有任何utopic用例,这个"非默认移动成员"的规则有意义吗?

c++ c++14 c++17

0
推荐指数
2
解决办法
330
查看次数

为什么std :: bind不能使用std :: filesystem :: path和std :: ostream?

我目前正在尝试编写一个程序,该程序使用std::binda std::filesystem::pathstd::ostream,作为引用,如下所示:

#include <functional>
#include <filesystem>
#include <ostream>
#include <iostream>

struct Buggy{
    static void something(const std::filesystem::path &path, std::ostream &out);
    void bind();
};

void Buggy::bind(){
    auto function = std::bind(&Buggy::something, std::placeholders::_1, std::cout);
    function(std::filesystem::path("./"));
}

void Buggy::something(const std::filesystem::path &path, std::ostream &out){
    out << path.string() << std::endl;
}

int main(){
    Buggy buggy;
    buggy.bind();
}
Run Code Online (Sandbox Code Playgroud)

我希望这段代码只输出" ./",但相反,它给了我大量的模板错误.为什么是这样?我对std::bind外观的使用对我来说是正确的.我g++ --std=c++17 bug4.cpp -o bug4 -lstdc++fs在Linux上编译.

我无法读取模板错误,因为它们与此标准库的实现细节混杂在一起.我尝试使用clang和gcc进行编译,两者都会产生类似的错误.通过搜索引擎搜索没有给出有用的结果.

c++ stdbind c++11 c++17

0
推荐指数
1
解决办法
100
查看次数