我习惯std::move在返回时不使用std::unique_ptr,因为这样做会禁止RVO.我有这种情况,我有一个本地std::unique_ptr,但返回类型是一个std::shared_ptr.以下是代码示例:
shared_ptr<int> getInt1() {
auto i = make_unique<int>();
*i = 1;
return i;
}
shared_ptr<int> getInt2() {
return make_unique<int>(2);
}
unique_ptr<int> getInt3() {
auto ptr = make_unique<int>(2);
return ptr;
}
int main() {
cout << *getInt1() << endl << *getInt2() << *getInt3() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC接受这两种情况,但Clang拒绝getInt1()使用此错误:
main.cpp:10:13: error: no viable conversion from 'std::unique_ptr<int, std::default_delete<int> >' to 'shared_ptr<int>'
return i;
^
Run Code Online (Sandbox Code Playgroud)
两个编译器都接受第三种情况.
哪一个错了?谢谢.
是概念定义的主体还是需要阻止未评估的上下文?例如.我可以std::declval安全使用吗?
template<typename T>
concept bool SomeConcept = requires(T a) {
{ a.someFunction(std::declval<int>()) } -> int;
};
Run Code Online (Sandbox Code Playgroud) 我今天尝试做类似的事.我很惊讶它没有编译.
struct Test {
// v----- Remove me to compile
// /*
static constexpr auto get_test1 = [](Test const& self) {
return self.test; // error, Test is incomplete
};
// */
// Handwritten version of the lambda
struct {
constexpr auto operator() (Test const& self) const {
return self.test; // ok
}
}
static constexpr get_test2{};
int test;
};
Run Code Online (Sandbox Code Playgroud)
它说Test范围内的类型不完整.然而,lambda的手写版确实有效.这是什么技术原因?这是标准中的疏忽,还是有一个特定的措辞Test在lambda中不完整?
我有一些看起来像这样的代码:
template<typename T>
struct memory_block {
// Very not copiable, this class cannot move
memory_block(memory_block const&) = delete;
memory_block(memory_block const&&) = delete;
memory_block(memory_block&) = delete;
memory_block(memory_block&&) = delete;
memory_block& operator=(memory_block const&) = delete;
memory_block& operator=(memory_block&&) = delete;
// The only constructor construct the `data` member with args
template<typename... Args>
explicit memory_block(Args&&... args) noexcept :
data{std::forward<Args>(args)...} {}
T data;
};
template<typename T>
struct special_block : memory_block<T> {
using memory_block<T>::memory_block;
std::vector<double> special_data;
};
// There is no other inheritance. The hierarchy ends …Run Code Online (Sandbox Code Playgroud) 考虑两个函数调用
foo({"a", 1}, {"b", "value"});
foo({"a", 1}, {"b", "value"}, {"c", 1.0});
Run Code Online (Sandbox Code Playgroud)
有没有办法foo为任意数量的参数对编写函数?
我正在思考一些问题
template <typename... Args>
void foo(std::pair<const char*, Args>&&...);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用.
gcc因错误而失败:
error: too many arguments to function 'void foo(std::pair<const char*, Args>&& ...) [with Args = {}]'
foo({"aa", 1});
Run Code Online (Sandbox Code Playgroud) c++ templates variadic-templates template-argument-deduction c++14
我想知道这个表达意味着什么?
typedef bool (*compareShapes)(const Shape* s1, const Shape* s2);
Run Code Online (Sandbox Code Playgroud)
这Shape是一堂课.
我正在寻找一种方法来从模板函数中的其他 lambda 中识别空的(无捕获的)lambda。我目前正在使用 C++17,但我也对 C++20 的答案感到好奇。
我的代码如下所示:
template<typename T>
auto func(T lambda) {
// The aguments of the lambdas are unknown
if constexpr (/* is captureless */) {
// do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
C++ 标准(17 或 20)是否保证可转换为函数指针的无捕获 lambda 也会使std::is_emptyyield 为真?
以这段代码为例:
auto a = []{}; // captureless
auto b = [c = 'z']{}; // has captures
static_assert(sizeof(a) == sizeof(b)); // Both are the same size
static_assert(!std::is_empty_v<decltype(b)>); // It has a `c` member
static_assert(std::is_empty_v<decltype(a)>); // Passes. It is guaranteed? …Run Code Online (Sandbox Code Playgroud) 考虑这个简单的独立代码:
template<typename T>
void foo();
void bar() {
int i;
auto l = [&i]() -> decltype(auto) {
decltype(auto) x = i;
foo<decltype(x)>();
foo<decltype(i)>();
return static_cast<decltype(i)>(i);
};
l();
foo<decltype(l())>();
}
Run Code Online (Sandbox Code Playgroud)
GCC 生成以下内容:
bar():
sub rsp, 8
call void foo<int&>()
call void foo<int>()
add rsp, 8
jmp void foo<int>()
Run Code Online (Sandbox Code Playgroud)
Clang 生成以下内容:
bar(): # @bar()
push rax
call void foo<int>()
call void foo<int>()
pop rax
jmp void foo<int>() # TAILCALL
Run Code Online (Sandbox Code Playgroud)
MSVC 生成以下内容:
void bar(void) PROC ; bar, COMDAT
$LN8:
sub rsp, 40 ; …Run Code Online (Sandbox Code Playgroud) 在下面的代码中
#include <type_traits>
template< typename T >
struct Allocator {
using element_type = std::aligned_storage_t< sizeof( T ) >;
};
template< typename T >
struct MPT {
static Allocator< MPT > allocator;
};
using RV = MPT< double >;
template<>
Allocator< RV > RV::allocator = {};
Run Code Online (Sandbox Code Playgroud)
g++ 产生以下错误:“sizeof”对不完整类型“MPT”的无效应用。
我尝试使用 Compiler Explorer ( https://godbolt.org/z/ran4or )使用 g++ 10.2 。Clang 和 MSVC 不会抱怨(参见https://godbolt.org/z/nsE5Yj和https://godbolt.org/z/7c7n4e)。
这真的是不完整类型的例子吗?哪个编译器在这里是正确的?
我有一些基本上这样做的代码:
struct Base {
virtual ~Base() = default;
virtual int forward() = 0;
};
struct Derived : Base {
int forward() override {
return 42;
}
};
typename std::aligned_storage<sizeof(Derived), alignof(Derived)>::type storage;
new (&storage) Derived{};
auto&& base = *reinterpret_cast<Base*>(&storage);
std::cout << base.forward() << std::endl;
Run Code Online (Sandbox Code Playgroud)
我非常怀疑它是明确定义的行为.如果它确实是未定义的行为,我该如何解决?在执行此操作的代码中reinterpret_cast,我只知道基类的类型.
另一方面,如果在所有情况下都有明确定义的行为,为什么这样做又如何?
仅保留对包含对象的引用不适用于此处.在我的代码中,我想在类型擦除列表上应用SBO,其中类型由我的库的用户创建,并且基本上扩展了Base类.
我在模板函数中添加元素,但在读取它的函数中,我无法知道Derived类型.我使用基类的全部原因是因为我只需要forward在我的代码中读取它的函数.
这是我的代码的样子:
union Storage {
// not used in this example, but it is in my code
void* pointer;
template<typename T>
Storage(T t) noexcept : storage{} …Run Code Online (Sandbox Code Playgroud)