以下代码无法编译:
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在这里返回左值引用?
这是一个完整的示例。
我有一个构建器类,我想将参数存储为引用,以便在后续构建中使用。
我想将可变数量的参数传递给我的类,使用类模板参数推导来推断模板参数,并将这些传递的参数作为引用存储在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&)
当我想改变数组的最后一个元素时,我总是使用[-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 ++有不同的条件吗?
我正在尝试void_t使用用法,但是以下代码给出了编译错误。is_fun是CompSstruct 中的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) 是否有一个特征返回特定类的基类,并假定不涉及多重继承?基本上像这样:
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) 我有一个从中创建临时对象的类。我可以将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) 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++风格来读取控制台输入
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++样式代码后的错误消息框:
Run Code Online (Sandbox Code Playgroud)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.
执行C风格代码后出错:
Run Code Online (Sandbox Code Playgroud)Exception triggered at 0x00007FF95C9398E9 (ucrtbased.dll) in Test.exe: 0xC0000005: Access violation when …
我正在尝试编写一个接受复杂参数的函数.假设它可以是一个类,或者它可以是一个类模板.函数内部的代码对于所有参数都是相同的,我不需要在任何地方引用参数的类型.所以,我想写这样的东西:
auto func(auto& someComplicatedClassInstance) {
return someComplicatedClassInstance.someMemberFunc();
}
Run Code Online (Sandbox Code Playgroud)
我不能只是写,template <typename T>因为如果T本身就是模板,它就不会起作用,而且auto函数参数在C++中不是.制作funclambda是唯一的方法吗?奇怪的是,为lambda启用相同的编译器功能,但不启用普通函数.在我的具体情况下,我正在写一个重载因为operator<<我不能使它成为一个lambda.
我正在通过网络发送一条消息,其中包含以下简单代码:
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)?