小编Art*_*zuk的帖子

如何从析构函数中调用const成员函数

当const对象被销毁时,有没有办法从析构函数中调用const成员函数?

考虑:

struct My_type { 
    ~My_type () { 
        show ();
    }

    void show () { 
        cout << "void show ()" << endl;
    }
    void show () const { 
        cout << "void show () const" << endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

用法:

My_type mt;
const My_type cmt;
mt.show ();
cmt.show ();
Run Code Online (Sandbox Code Playgroud)

输出:

void show ()
void show () const
void show ()
void show ()
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下为什么cmt被销毁时没有调用const版本的show ?

c++ destructor c++11

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

从成员构造函数抛出异常(大括号初始化程序与初始化程序列表)

我在理解在成员对象初始化期间抛出异常(来自构造函数)时发生的事情时,我已经失去了信心(可能还有2个小时).

让我告诉你一个例子:

int init (int f) {
    throw f;
}

struct X {
    X (int f) : n {init (f)} {}
    int n;
};

struct P {
    X x {20};
};
Run Code Online (Sandbox Code Playgroud)

和用法:

int main (int argc, char** argv) {
    try {
        P p {};
    }
    catch (int n) {
        std::cout << n << "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码(C++ 11模式)编译得很好(使用GCC 7.2.1),在Linux(Centos 7.4.1708)下我得到:

terminate called after throwing an instance of 'int'
[1]    1242 abort (core dumped)  ./main
Run Code Online (Sandbox Code Playgroud)

问题是:为什么? 为什么catch()不采取部分?

我已经跟踪了这个问题,这意味着当我的 …

c++

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

{object}的类型是什么?

请考虑以下代码:

void foo (M&) {}

M m;
foo ({m});
Run Code Online (Sandbox Code Playgroud)

因此,表达式{m}被视为rvalue引用,这就是此代码无法编译的原因.

这是真的{object}总是产生临时对象吗?

如果没有,那么如何确定它何时发生?如果是,请考虑以下代码:

struct M {};

struct I {
    I (M&) {}
};

struct MM {
    MM (M& p)
    : m (p), i ( {p} )
    {}

    M& m;
    I i;
};

M m;
MM mm {m};
Run Code Online (Sandbox Code Playgroud)

这里完全没有问题,那么{m}从第一个例子和{p}第二个例子之间的区别是什么?

编译器(GCC 4.8.1)结果(第一个例子):

main.cpp:366:13: error: invalid initialization of non-const reference of type ‘M&’ from an rvalue of type ‘<brace-enclosed initializer list>’
     foo ({m});
             ^
main.cpp:359:6: error: …
Run Code Online (Sandbox Code Playgroud)

c++

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

继承构造函数时std :: is_nothrow_constructible

考虑以下两个例子:

struct A {
    A () noexcept = default;
};

struct B : A {
    B () noexcept = default;

    template <typename T>
    B (T) noexcept {}
};

struct C : A {
    using A::A;

    template <typename T>
    C (T) noexcept {} 
};
Run Code Online (Sandbox Code Playgroud)

和用法:

std::cout << std::is_nothrow_constructible<B>::value << std::endl; // (X)
std::cout << std::is_nothrow_constructible<B, int>::value << std::endl;

std::cout << std::is_nothrow_constructible<C>::value << std::endl; // (Y)
std::cout << std::is_nothrow_constructible<C, int>::value << std::endl;
Run Code Online (Sandbox Code Playgroud)

输出是:

1
1
0
1
Run Code Online (Sandbox Code Playgroud)

使用的编译器:GCC 4.8.1.

所以,如果我显式写默认B构造函数, …

c++ c++11

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

展开两个参数包

请考虑以下代码:

static constexpr size_t Num {2};
struct S {
    std::array<size_t, Num> get () { return {1, 2}; }
};

struct S1 : S {};
struct S2 : S {};

struct M {
    template <typename T>
    typename std::enable_if<std::is_same<T, S1>::value, S1>::type get () const { 
        return S1 {}; 
    }

    template <typename T>
    typename std::enable_if<std::is_same<T, S2>::value, S2>::type get () const { 
        return S2 {}; 
    }
};
Run Code Online (Sandbox Code Playgroud)

我想要一个合并两个或多个std::arrays 的功能std::array.

到目前为止,我结束了这样的事情:

template <typename Mode, typename... Rs, size_t... Ns>
std::array<size_t, sizeof... (Rs)*Num> …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

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

将转发引用传递给线程包装器类

我们先来看看具体的功能:

void boo1 () { std::cout << "boo1\n"; }
void boo2 (std::string) { std::cout << "boo2\n"; }

struct X {
    void boo3 () { std::cout << "boo3\n"; }
    void boo4 (std::string) { std::cout << "boo4\n"; }
};
Run Code Online (Sandbox Code Playgroud)

我希望这些函数可以通过一些"保护"功能来执行,它可以进行异常保护(下面的说明).所以,我写了两个函数,一个用于自由函数,另一个用于成员函数:

template <typename C, typename... Args>
typename std::enable_if<!std::is_member_function_pointer<C>::value, void>::type
foo (C&& c, Args&&... args) {
    std::cout << "not memfun\n";
    c (std::forward<Args> (args)...);
}

template <typename C, typename T, typename... Args>
typename std::enable_if<std::is_member_function_pointer<C>::value, void>::type
foo (C&& c, T* o, Args&&... args) {
    std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading c++11

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

使用多个返回值初始化多个成员

从C++ 17开始我就能做到

std::pair<int, double> init () {
    return std::make_pair (1, 1.2);
}

void foo () {
    const auto [x, y] = init ();
    std::cout << x << " " << y << "\n";
}
Run Code Online (Sandbox Code Playgroud)

这很酷,但有什么办法可以一次初始化多个成员吗?我的意思是:

struct X {
    X () : [x, y] {read_from_file_all_values ()} {}

    std::pair<int, double> read_from_file_all_values () {
        // open file, read all values, return all
        return std::make_pair (1, 1.2);
    }

    const int x;
    const double y;
};
Run Code Online (Sandbox Code Playgroud)

我知道,由于语法原因,这不起作用.我也知道我可以将所有值存储在相应的std::pair成员里面X,并使getter过载丑陋的std::get<N> ()语法,但是有什么办法可以用单个init() …

c++ multiple-return-values c++17

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

无法在初始化时转换Type

我想我错过了什么,我不知道到底是什么.我们来看看代码片段.

template <typename T>
struct Foo { 
    Foo (int n, int p, string s, T t = {})
    : m_n {n}, m_p {p}, m_s {s}, m_t {t}
    {}

    const int m_n;
    const int m_p;
    const string m_s;
    T m_t;
};
Run Code Online (Sandbox Code Playgroud)

用法如下:

Foo<int> f_int1 {1, 2, "A", 155};
Foo<int> f_int2 {1, 2, "A"};
Run Code Online (Sandbox Code Playgroud)

一切都像预期的那样.但是当我想将用户定义的类型作为Foo的T参数时,会发生一些错误.考虑:

struct Boo {
    int z;
    int l;
};
Run Code Online (Sandbox Code Playgroud)

用法:

Foo<Boo> f_boo1 {1, 2, "A"};
Foo<Boo> f_boo2 {1, 2, "A", {1, 2}};
Run Code Online (Sandbox Code Playgroud)

这两条指令都给出了(gcc 4.8.1):

cannot convert ‘Boo’ to …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 list-initialization

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

返回类型取决于算术运算中的顺序.这是对的吗?

请考虑以下代码段:

template <typename U>
struct Un {
    Un (int p) : n {p} {}

    U operator+ (U v) const {
        return U {n + v.n};
    }

    int n {};
};

struct R : Un<R> {
    using Un::Un;
};

struct D : Un<D> {
    using Un::Un;
    D (R v) : Un {v.n} {}
    operator R () const {
        return n;
    }
};
Run Code Online (Sandbox Code Playgroud)

用法如下:

template <typename T>
void what_type (T t) {
    std::cout << "type R = " << std::is_same<T, R>::value << …
Run Code Online (Sandbox Code Playgroud)

c++

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

std::vector&lt;T&gt;::insert 和 std::move_iterator&lt;T&gt; 它们如何协同工作?

我对此不太确定,所以请解释一下它是如何工作的。

让我们考虑以下代码。

std::vector<std::string> vec {};
 
void add (std::vector<std::string>&& v) {
    using iter = std::vector<std::string>::iterator;
    vec.insert (vec.end (), 
                std::move_iterator<iter> (v.begin ()), 
                std::move_iterator<iter> (v.end ()));
}
Run Code Online (Sandbox Code Playgroud)

所有元素都会v被移动吗?std::vector<T>::insert()对于范围版本需要第一个最后一个迭代器,因此有了这样的代码,它如何知道v.begin()+1 也必须移动?的实现是否std::vector<T>::insert()区分“正常”和“移动”迭代器?

c++ c++11

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