标签: c++17

如果一个唯一的指针是一个捕获的值,为什么它不能在lambda内移动?

以下代码无法编译:

struct S{};

void foo(std::unique_ptr<S> ptr)
{
    auto l = [p = std::move(ptr)]()
    {
        auto p2 = std::move(p);
    };
    l();
}
Run Code Online (Sandbox Code Playgroud)

原因是std::move(p)返回一个左值引用,因此编译器尝试调用被删除的复制构造函数。为什么move在这里返回左值引用?

是一个完整的示例。

c++ c++17

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

如何从参数包构造引用的std :: tuple?

我有一个构建器类,我想将参数存储为引用,以便在后续构建中使用。

我想将可变数量的参数传递给我的类,使用类模板参数推导来推断模板参数,并将这些传递的参数作为引用存储在std :: tuple中。

从参数包转换为引用的std :: tuple的最简单方法是什么?

我发现std :: forward_as_tuple的功能与我想要的类似,但是我不想要转发引用,而且它在成员元组的初始化期间提供了语法错误。

template <typename... Ts>
struct Builder
{
using ArgsT = decltype(std::forward_as_tuple(Ts{}...));

ArgsT args_;

Builder(Ts&... ts) : args_(ts...) {}
};

int main()
{
    struct Foo
    {
        int a;
        double b;
    };

    Foo foo{};
    Builder fooBuilder{foo.a, foo.b};
}
Run Code Online (Sandbox Code Playgroud)

语法错误是:

错误:没有匹配的调用函数 std::tuple<int&&, double&&>::tuple(int&, double&)

c++ variadic-templates stdtuple c++17

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

在数组中向后计数。[-1]

当我想改变数组的最后一个元素时,我总是使用[-1]作为最后一个元素。

#include <iostream>
using namespace std;
int main(){
    int arr[10]{};
    arr[0]=10;
    arr[-1]=100;
    cout<<arr[-1]<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后我的老师说:“ C ++不支持数组的这种行为。我应该使用arr [9]作为最后一个元素,而“ arr [-1] = 100”实际上将在其中一个元素之前的区域中存储1000。数组开始。这会导致崩溃,因为该值超出了数组的范围。” 有人可以解释为什么吗?

注意:我是python程序员。当我在列表中使用-1时,我在python中没有问题。C ++有不同的条件吗?

c++ arrays c++17

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

如何正确使用C ++ void_t?

我正在尝试void_t使用用法,但是以下代码给出了编译错误。is_funCompSstruct 中的typedef,所以我认为Comp::is_fun应该是有效的。

我有什么想念的吗?

template <typename T, typename Comp, typename = void_t<>>
class my_set
{
    public:
        my_set() : mem(5){}
        T mem;
};

template <typename T, typename Comp, void_t<typename Comp::is_fun> >
class my_set 
{
    public:
        my_set() : mem(10){}
        T mem;
};

struct CompS
{
    typedef int is_fun;
};

int main()
{
    my_set<int, CompS> a;
    std::cout << a.mem << std::endl;


    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:

   voidt.cpp:17:38: error: ‘void’ is not a valid type for a template …
Run Code Online (Sandbox Code Playgroud)

c++ c++17 void-t

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

腐烂至基层

是否有一个特征返回特定类的基类,并假定不涉及多重继承?基本上像这样:

struct Base
{

};

struct Derived : public Base
{

};

struct DerivedDerived : public Derived
{

};

static_assert(std::is_same_v<base<DerivedDerived>::type,Derived>);
static_assert(std::is_same_v<base<Derived>::type,Base>);
static_assert(std::is_same_v<base<Base>::type,Base>);
// with levels
static_assert(std::is_same_v<base<0,DerivedDerived>::type,Base>);
static_assert(std::is_same_v<base<1,DerivedDerived>::type,Derived>);
static_assert(std::is_same_v<base<2,DerivedDerived>::type,DerivedDerived>);
static_assert(std::is_same_v<base<0,Derived>::type,Base>);
static_assert(std::is_same_v<base<1,Derived>::type,Derived>);
Run Code Online (Sandbox Code Playgroud)

c++ templates type-traits c++17

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

const对临时对象的引用不会延长其寿命

我有一个从中创建临时对象的类。我可以将const引用绑定到此临时对象,并且它可以按预期工作。但是,如果我在该临时对象上调用返回std :: move(* this)的成员函数并绑定到此返回值,则该函数将无法正常工作。下面的短代码重现了我的问题,这是不言自明的。

#include <iostream>
#include <cstdlib>
#include <vector>

class myval {
    public:
    std::vector<int> i;
    myval(int i) : i({i}) {}
    myval(const myval& v) = delete;
    myval(myval&& v) : i(std::move(v.i)) {}
    myval&& addone() && {
        i[0]++;
        return std::move(*this);
    }

};

int main()
{
    //Object is moved, works like expected
    const auto moved_value = myval{7}.addone();
    std::cout << moved_value.i[0] << std::endl;

    //Const reference is supposed extend the lifetime of a temporary object
    const auto& u = myval{7};
    //Prints 7, as expected
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ c++14 c++17

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

std :: apply可能无法正确实施

std :: apply在很少的stackoverflow答案和n3658,n3915中提到,通常定义为:

template <typename F, typename Tuple, size_t... I>
decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {
  return forward<F>(f)(get<I>(forward<Tuple>(t))...);
}

template <typename F, typename Tuple>
decltype(auto) apply(F&& f, Tuple&& t) {
  using Indices = make_index_sequence<tuple_size<decay_t<Tuple>>::value>;
  return apply_impl(forward<F>(f), forward<Tuple>(t), Indices{});
}
Run Code Online (Sandbox Code Playgroud)

但是,参考实现std :: apply函数无法在此类上下文中进行编译(使用clang 3.8和gcc 5.2进行测试):

std::apply ([] (int&) {} , std::make_tuple (42));
Run Code Online (Sandbox Code Playgroud)

一种可能的解决方法是简单地从apply_impl中删除std :: forward <Tuple>,但保持通用引用不变:

template <typename F, typename Tuple, size_t... I>
decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {
  return forward<F>(f)(get<I>(t)...);
}
Run Code Online (Sandbox Code Playgroud)

这种解决方法有任何缺点吗?有更方便的解决方案吗? …

c++ c++11 c++14 c++17

-1
推荐指数
1
解决办法
1213
查看次数

控制台未正确读取输入字符串

我试图通过执行C++风格来读取控制台输入

int main()
{
    std::string str;
    std::getline(std::cin, str);
    // also tested: std::cin >> str;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

和C风格

int main()
{
    char* str = new char[20];
    scanf_s("%s", str);
    delete[] str;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是如果我输入一个字符串然后按回车键,控制台中的光标将不会跳转到下一行,它会跳转到输入命令所在行的第一列.输入第二个键会导致错误:

执行C++样式代码后的错误消息框:

Debug Assertion Failed!

Program: D:\_extern\Test\Test.exe
File: minkernel\crts\ucrt\src\appcrt\lowio\read.cpp
Line: 259

Expression: static_cast<void const*>(source_buffer) == static_cast<void const*>(result_buffer)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
Run Code Online (Sandbox Code Playgroud)

执行C风格代码后出错:

Exception triggered at 0x00007FF95C9398E9 (ucrtbased.dll) in Test.exe: 0xC0000005: Access violation when …
Run Code Online (Sandbox Code Playgroud)

c++ console winapi c++17

-1
推荐指数
1
解决办法
92
查看次数

模板函数:是否有接受任何参数类型的语法,因为'auto'对lambdas有效?

我正在尝试编写一个接受复杂参数的函数.假设它可以是一个类,或者它可以是一个类模板.函数内部的代码对于所有参数都是相同的,我不需要在任何地方引用参数的类型.所以,我想写这样的东西:

auto func(auto& someComplicatedClassInstance) {
   return someComplicatedClassInstance.someMemberFunc();
}
Run Code Online (Sandbox Code Playgroud)

我不能只是写,template <typename T>因为如果T本身就是模板,它就不会起作用,而且auto函数参数在C++中不是.制作funclambda是唯一的方法吗?奇怪的是,为lambda启用相同的编译器功能,但不启用普通函数.在我的具体情况下,我正在写一个重载因为operator<<我不能使它成为一个lambda.

c++ c++17

-1
推荐指数
1
解决办法
71
查看次数

C++使用atoi()转换单个字符而不是多个字符

我正在通过网络发送一条消息,其中包含以下简单代码:

SSL_write(ssl, argv[1], strlen(argv[1]));
Run Code Online (Sandbox Code Playgroud)

然后,我接收服务器上的消息并将消息的第一个字符转换为int,具有以下代码:

char buf[1024] = {0};
SSL_read(ssl, buf, sizeof(buf));
std::cout << atoi(&buf[0]);
Run Code Online (Sandbox Code Playgroud)

此代码工作得相当好,因为如果字符串类似于"1foo",服务器将打印出"1"到控制台.但是,如果字符串是"12foo",则服务器将打印出"12"而不是"1".

我该如何解决这个问题,所以服务器只打印出字符串的第一个字符(作为int)?

c++ string c++17

-1
推荐指数
1
解决办法
75
查看次数