小编Gui*_*cot的帖子

将本地unique_ptr作为shared_ptr返回

我习惯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)

这是coliru的两个案例:GCC,Clang

两个编译器都接受第三种情况.

哪一个错了?谢谢.

c++ gcc clang language-lawyer c++14

15
推荐指数
2
解决办法
1083
查看次数

身体是否需要阻止未评估的背景?

是概念定义的主体还是需要阻止未评估的上下文?例如.我可以std::declval安全使用吗?

template<typename T>
concept bool SomeConcept = requires(T a) {
    { a.someFunction(std::declval<int>()) } -> int;
};
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts

15
推荐指数
1
解决办法
216
查看次数

为什么静态lambda成员的封闭类型不完整?

我今天尝试做类似的事.我很惊讶它没有编译.

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中不完整?

c++ lambda language-lawyer c++17

15
推荐指数
1
解决办法
350
查看次数

是否将指向第一个成员的指针解释为类本身定义正确?

我有一些看起来像这样的代码:

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)

c++ casting void-pointers c++11

15
推荐指数
1
解决办法
639
查看次数

使用可变参数模板进行隐式转换

考虑两个函数调用

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

14
推荐指数
3
解决办法
423
查看次数

理解复杂的typedef表达式

我想知道这个表达意味着什么?

typedef bool (*compareShapes)(const Shape* s1, const Shape* s2);
Run Code Online (Sandbox Code Playgroud)

Shape是一堂课.

c++ c++11

12
推荐指数
4
解决办法
2215
查看次数

标准是否保证无捕获 lambda 为空?

我正在寻找一种方法来从模板函数中的其他 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)

c++ lambda c++17 c++20

12
推荐指数
1
解决办法
318
查看次数

可以捕获的实体的 decltype:它应该产生 lambda 之外的实体类型吗?

考虑这个简单的独立代码:

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)

c++ lambda language-lawyer decltype-auto

11
推荐指数
0
解决办法
103
查看次数

“sizeof”对不完整类型错误的意外无效应用

在下面的代码中

#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/nsE5Yjhttps://godbolt.org/z/7c7n4e)。

这真的是不完整类型的例子吗?哪个编译器在这里是正确的?

c++ templates g++ language-lawyer

10
推荐指数
0
解决办法
135
查看次数

如何使用aligned_storage和polymorphism来避免未定义的行为

我有一些基本上这样做的代码:

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)

c++ reinterpret-cast c++11

9
推荐指数
1
解决办法
666
查看次数