小编Gre*_*ape的帖子

所有版本的GCC都与默认成员初始化器相媲美,它捕获了这个,并与继承的构造函数相结合

这个故事与我之前的问题类似.支持C++ 11的所有GCC版本都具有这种确切的行为.我找不到任何其他编译器与我的测试用例斗争.

测试用例:

struct BaseFooWrapper
{
    BaseFooWrapper(int qux)
    { }
};

struct Foo
{
    Foo(BaseFooWrapper & foo)
        : foo(foo)
    { }

    BaseFooWrapper & foo;
};

struct SomeFooWrapper : public BaseFooWrapper
{
    using BaseFooWrapper::BaseFooWrapper;


    Foo foo{*this};
};

int main()
{
    SomeFooWrapper wrapped_foo(1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

住在godbolt.com上


这段代码用clang(3.4到4.0),icc(16,17),Visual C++(19.00.23506)编译.

如果我用手写版本替换构造函数继承,那么GCC开始编译代码:

struct BaseFooWrapper
{
    BaseFooWrapper(int qux)
    { }
};

struct Foo
{
    Foo(BaseFooWrapper & foo)
        : foo(foo)
    { }

    BaseFooWrapper …
Run Code Online (Sandbox Code Playgroud)

c++ gcc c++11 inheriting-constructors

10
推荐指数
1
解决办法
420
查看次数

构造函数中的语法错误采用默认参数`std :: map`

考虑简单的代码片段

#include <map>
#include <string>


struct Foo
{
    Foo(const std::map<std::string, int> & bar = std::map<std::string, int>())
        :bar(bar)
    { }

    std::map<std::string, int> bar;
};

int main(int argc, char ** argv)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我像这样编译它时:clang++ -o foo foo.cpp我遇到错误:

foo.cpp:7:73: error: expected ')'
    Foo(const std::map<std::string, int> bar = std::map<std::string, int>())
                                                                        ^
foo.cpp:7:8: note: to match this '('
    Foo(const std::map<std::string, int> bar = std::map<std::string, int>())
       ^
foo.cpp:7:68: error: expected '>'
    Foo(const std::map<std::string, int> bar = std::map<std::string, int>())
                                                                   ^
Run Code Online (Sandbox Code Playgroud)

clang 3.2和 …

c++ clang

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

有关AFT(缩写功能模板)的争议是什么?

为什么这个功能看起来如此有争议?我看到它没有与其他概念TS一起合并到C++ 20中.通过网络搜索,除了可以应用于几乎任何新的C++特性的通用参数之外,我找不到合理的参数.

人们如此害怕什么?那里有什么陷阱?毕竟,我们已经有了通用的lambda.

c++ c++-concepts c++20

8
推荐指数
1
解决办法
276
查看次数

std ::移动和地图分配

关于标准如何管理这种情况,我有点困惑:

struct Foo {
    Foo & operator = (std::string xxx)
    {
        x = std::move(xxx);
        return *this;
    }

    std::string x;
};

std::map<std::string, Foo> bar;

std::string baz = "some string";

bar[baz] = std::move(baz);
Run Code Online (Sandbox Code Playgroud)

编译器是否可以生成代码,以便用于初始化和引用元素(初始化)之前baz移动代码?或者这段代码是否安全且没有未定义的行为barstd::string xxx

c++ move-semantics c++11

6
推荐指数
1
解决办法
832
查看次数

为什么“累积”没有进入 C++20 的范围?

我怀疑这accumulate不是唯一没有成功的算法。

也许现在有更好的方法来在一个范围内执行累积(折叠),因此accumulate已经过时了?

c++ range-v3 c++20

6
推荐指数
1
解决办法
198
查看次数

分段错误和RAII

这更像是一种哲学类型的问题.

C++中,我们有很好的闪亮成语 - RAII.但我常常认为它不完整.它与我的应用程序可以用SIGSEGV杀死的事实不太一致.

我知道,我知道,像你这样的程序是不正确的.但令人遗憾的是,在POSIX(特别是Linux)上,您可以分配超出物理内存限制并在执行过程中满足SIGSEGV,使用正确分配的内存.

你可能会说:"应用程序死了,你为什么要关心那些没有被调用的糟糕的析构函数?".遗憾的是,有些资源在应用程序终止时不会自动释放,例如文件系统实体.

我现在非常厌倦了设计黑客,破坏良好的应用程序设计以应对这一点.所以,我要问的是为这类问题提供一个漂亮,优雅的解决方案.

编辑:

似乎我错了,Linux应用程序被内核寻呼机杀死.在这种情况下,问题仍然是相同的,但申请死亡的原因是不同的.

代码段:

struct UnlinkGuard
{
    UnlinkGuard(const std::string path_to_file)
        : _path_to_file(path_to_file)
    { }

    ~UnlinkGuard() {
        unlink();
    }

    bool unlink() {
        if (_path_to_file.empty())
            return true;

        if (::unlink(_path_to_file.c_str())) {
            /// Probably some logging.
            return false;
        }

        disengage();
        return true;
    }

    void disengage() {
        _path_to_file.clear();
    }

private:
    std::string _path_to_file;
};

void foo()
{
    /// Pick path to temp file.
    std::string path_to_temp_file = "...";

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

c++ posix exception raii segmentation-fault

5
推荐指数
1
解决办法
272
查看次数

std :: shared_ptr <T>:r值指向T的隐式构造函数

我非常支持制作std::shared_ptr<T>接受T *显式的构造函数的想法.当你正在查看堆损坏的原因时,它有助于挽救不眠之夜.Scott Meyers对此给出了很好的解释.


但是......如果我给它一个rvalue指针不明白吗?我可以这样做:

/// (1)
std::shared_ptr<T> t = new T;
Run Code Online (Sandbox Code Playgroud)

要么

/// (2)
T * giveaway = new T;
std::shared_ptr<T> t = std::move(giveaway);
Run Code Online (Sandbox Code Playgroud)

或者是现实生活中更痛苦的一个案例

/// (3)
void foo(std::shared_ptr<T> t);
/// ...
foo(new T);
Run Code Online (Sandbox Code Playgroud)

至于我,所有这些案例都足够明确.

情况(1)是一个prvalue,我不可能搞砸两个指针.至少不过是使用:

std::shared_ptr<T> t{new T};
Run Code Online (Sandbox Code Playgroud)

案例(2)非常明确.一致同意,在你移动了某些东西后,它的值变得不确定.所以使用它完全取决于你.

案例(3)rvalue再次出现.


(Q1)这是标准委员会的俯视吗?

(Q2)有这个原因吗?

(Q3)隐式构造函数是否有机会接受rvalue在C++ 14中出现?

c++ rvalue shared-ptr c++11

5
推荐指数
1
解决办法
214
查看次数

boost::asio::ssl::context 可以在多个 SSL 流之间共享吗?

在互联网上挖掘了几个小时,我找不到我的问题的答案。

我的模型是这样的:我有一个boost::asio::ssl::context用于创建实例的共享boost::asio::ssl::stream. 然后流对象被传递到不同的线程。

这个模型线程安全吗?是否可以boost::asio::ssl::context在构建将同时使用的不同 SSL 流对象时使用相同的内容?

在将此问题标记为重复之前,仔细阅读说明。谢谢!

我的具体情况是,线程之间没有共享对象。所以Boost.Asio SSL 线程安全 线程安全中所说的任何内容都不会影响我的情况。我boost::asio::ssl::context从单个线程访问。

c++ ssl multithreading boost-asio

5
推荐指数
1
解决办法
946
查看次数

有没有理由说std :: make_shared/std :: make_unique不使用列表初始化?

具体来说:直接列表初始化(cppreference.com (3)).

C++ 11中引入了两者std::make_shared统一初始化功能.所以我们可以在堆上分配对象时使用聚合初始化:.这是直接初始化没有构造函数的对象的好方法,例如聚合,pod等.new Foo{1, "2", 3.0f}

根据我的经验,现实生活场景,例如在函数中声明临时结构,有效地为lambda提供一组参数变得非常普遍:

void foo()
{
    struct LambdaArgs
    {
        std::string arg1;
        std::string arg2;
        std::string arg3;
    };

    auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});

    auto lambda = [args] {
        /// ...
    };

    /// Use lambda
    /// ...
}
Run Code Online (Sandbox Code Playgroud)

这里auto args = std::make_shared<LambdaArgs>("1", "2", "3");应该很好但不会起作用,因为std::make_shared通常实现为:

template<typename T, typename... Args>
std::shared_ptr<T> make_shared(Args && ...args)
{
    return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)

所以我们坚持了auto …

c++ std shared-ptr c++11

5
推荐指数
1
解决办法
1425
查看次数

忽略候选模板:推导出参数的冲突类型:<const T&> vs <T&>

我的类中有一个成员函数_wrapper,它封装了一些围绕其他函数族的常见逻辑.此包装函数接受指向正在包装的函数及其参数的指针.

我的类中的包装器实现类似于在此示例类中完成的方式Foo:

#include <functional>

class Foo
{
public:
    void bar1(int a)
    {
        /// No-op.
    }

    void bar1(int a, int b)
    {
        /// No-op.
    }

    void bar2(const int & a)
    {
        /// No-op.
    }

    void foo(int x)
    {
        _wrapper_bar1(x);           /// No problems to deduce type
        _wrapper_bar2(x);           /// No problems to deduce type

        _wrapper(&Foo::bar1, x);    /// Deduction fails
        _wrapper(&Foo::bar2, x);    /// Deduction fails
    }

private:
    template <typename ...Args>
    void _wrapper(void (Foo::*method) (Args ...), Args && ...args)
    {
        /// …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

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

Clang的libc ++:在std :: chrono :: duration的定义中使用long long

在32位平台上的libc ++中,int64_t被定义为别名long long.在64位平台上:long.

另一方面,在std::chrono::duration别名的定义中,您可以在这里 long long不经意地使用:

typedef duration<long long,         nano> nanoseconds;
typedef duration<long long,        micro> microseconds;
typedef duration<long long,        milli> milliseconds;
typedef duration<long long              > seconds;
typedef duration<     long, ratio<  60> > minutes;
typedef duration<     long, ratio<3600> > hours;
Run Code Online (Sandbox Code Playgroud)

因此,例如,当我需要严格8字节长的类型时,我会期望

  foo(uint64_t);
  foo(int64_t);
Run Code Online (Sandbox Code Playgroud)

是一个相当便携的解决方案.但是在libc ++的情况下,chrono它不是真的.除了编写类似于你自己的逻辑之外,没有可移植的方法<cstdint>.即,定义的两个额外的定义,foo称取long longunsigned long long.

或者另一个例子:

  foo(int8_t);
  foo(int16_t);
  foo(int32_t);
  foo(int64_t);
Run Code Online (Sandbox Code Playgroud)

foo(duration.count())在这种情况下,呼叫将是模棱两可的.

那么什么用的点long long是不大于long但它的等级大于 …

c++ clang c++11 libc++

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