小编cur*_*guy的帖子

在C++中使用指令与使用声明交换

请参考以下代码:

#include <algorithm>

namespace N
{

    template <typename T>
    class C
    {
    public:
        void SwapWith(C & c)
        {
            using namespace std; // (1)
            //using std::swap;   // (2)
            swap(a, c.a);
        }
    private:
        int a;
    };

    template <typename T>
    void swap(C<T> & c1, C<T> & c2)
    {
        c1.SwapWith(c2);
    }

}

namespace std
{

    template<typename T> void swap(N::C<T> & c1, N::C<T> & c2)
    {
        c1.SwapWith(c2);
    }

}
Run Code Online (Sandbox Code Playgroud)

如上所述,代码无法在Visual Studio 2008/2010上编译.错误是:

'void N::swap(N::C<T> &,N::C<T> &)' : could not deduce template argument for 'N::C<T> &' …
Run Code Online (Sandbox Code Playgroud)

c++ swap using-directives using-declaration

14
推荐指数
2
解决办法
8370
查看次数

constexpr中的字节序

我想创建一个constexpr函数来返回系统的字节序,如下所示:

constexpr bool IsBigEndian()
{
    constexpr int32_t one = 1;
    return (reinterpret_cast<const int8_t&>(one) == 0);
}
Run Code Online (Sandbox Code Playgroud)

现在,由于函数将在编译时而不是在实际的目标机器上执行,C++规范给出了什么保证以确保返回正确的结果?

c++ endianness language-lawyer constant-expression

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

嵌套类的同班朋友可以访问外部类成员吗?

clang ++,g ++和MSVC 在以下代码上存在分歧

class A {
private:
    enum class E { NO, YES };
    class B {
    private:
        friend E f1() { return E::YES; }
        // friend E f2();
    };
};

// A::E f2() { return A::E::YES; }

int main() {}
Run Code Online (Sandbox Code Playgroud)

clang ++接受如下所示的代码。g ++以及MSVC抱怨在f1A::E不可访问。如果f2未注释函数,则所有三个编译器都会抱怨其A::E无法访问的定义。

f1在事实上是否有效?

我发现的相关标准件有:

[class.access.nest]

嵌套类是成员,因此具有与任何其他成员相同的访问权限。

尽管仅此一项并不意味着嵌套类的朋友拥有与嵌套类相同的权限。

[class.access.base] / 5

对成员的访问受该成员所在的类影响。该命名类是在其中查找并找到成员名称的类。如果在类中命名成员,m则可以在R点访问成员N

  • m作为N公共成员,或

  • m作为的成员N是私有成员,并且 …

c++ access-control inner-classes language-lawyer c++17

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

私有继承:名称查找错误

我有以下不编译的代码示例:

#include <stdio.h>

namespace my
{
    class base1
    { // line 6
    };

    class base2: private base1
    {
    };

    class derived: private base2
    {
    public:
        // The following function just wants to print a pointer, nothing else!
        void print(base1* pointer) {printf("%p\n", pointer);}
    };
}
Run Code Online (Sandbox Code Playgroud)

gcc打印的错误是:

test.cpp:6:错误:`class my :: base1'无法访问

test.cpp:17:错误:在此上下文中

现在,我可以猜出问题是什么:在查看声明时print,编译器会看到base1并认为:base1是基类子对象derived* this,但是您无法访问它!虽然我打算这base1应该只是一个类型名称.

我怎么能在C++标准中看到这是一个正确的行为,而不是编译器中的错误(我确定它不是一个错误;我检查过的所有编译器都表现得如此)?

我该如何解决这个错误?所有以下修复工作,但我应该选择哪一个?

void print(class base1*pointer){}

void print(:: my :: base1*pointer){}

class base1; void print(base1*pointer){}


编辑:

int …
Run Code Online (Sandbox Code Playgroud)

c++ class-members private-inheritance name-lookup

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

C++构造函数:为什么这个虚函数调用不安全?

这是来自C++ 11标准sec 12.7.4.这相当令人困惑.

  1. 文中的最后一句话究竟是什么意思?
  2. 为什么最后一个方法调用B::B未定义?不是它只是打电话a.A::f

4构造函数,包括虚函数(10.3),可以在构造或销毁期间调用(12.6.2).当从构造函数或析构函数直接或间接调用虚函数时,包括在构造或销毁类的非静态数据成员期间,以及调用所适用的对象是正在构造的对象(称为x)或者破坏,被调用的函数是构造函数或析构函数类中的最终覆盖,而不是在更多派生类中覆盖它.如果虚函数调用使用显式类成员访问(5.2.5)并且对象表达式引用x的完整对象或该对象的基类子对象之一但不是x或其基类子对象之一,则行为未定义.[例如:

struct V {
 virtual void f();
 virtual void g();
};

struct A : virtual V {
 virtual void f();
};

struct B : virtual V {
 virtual void g();
 B(V*, A*);
};

struct D : A, B {
 virtual void f();
 virtual void g();
 D() : B((A*)this, this) { }
};

B::B(V* v, A* a) {
 f(); // calls V::f, not A::f
 g(); // calls B::g, not D::g
 v->g(); // …
Run Code Online (Sandbox Code Playgroud)

c++ constructor virtual-functions virtual-inheritance c++11

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

从抽象基类的多个部分实现继承?

是否有可能有一些抽象接口的部分实现,然后通过使用多个继承这些部分实现收集到一个具体的类中

我有以下示例代码:

#include <iostream>

struct Base
{
    virtual void F1() = 0;
    virtual void F2() = 0;
};

struct D1 : Base
{
    void F1() override { std::cout << __func__ << std::endl; }
};

struct D2 : Base
{
    void F2() override { std::cout << __func__ << std::endl; }
};

// collection of the two partial implementations to form the concrete implementation
struct Deriv : D1, D2
{
    using D1::F1; // I …
Run Code Online (Sandbox Code Playgroud)

c++ multiple-inheritance virtual-inheritance

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

使用new char []或malloc的结果来表示浮动*是UB(严格别名冲突)吗?

哪些代码有UB(具体来说,哪些违反了严格的别名规则)?

void a() {
    std::vector<char> v(sizeof(float));
    float *f = reinterpret_cast<float *>(v.data());
    *f = 42;
}

void b() {
    char *a = new char[sizeof(float)];
    float *f = reinterpret_cast<float *>(a);
    *f = 42;
}

void c() {
    char *a = new char[sizeof(float)];
    float *f = new(a) float;
    *f = 42;
}

void d() {
    char *a = (char*)malloc(sizeof(float));
    float *f = reinterpret_cast<float *>(a);
    *f = 42;
}

void e() {
    char *a = (char*)operator new(sizeof(float));
    float *f = reinterpret_cast<float *>(a);
    *f = …
Run Code Online (Sandbox Code Playgroud)

c++ malloc strict-aliasing object-lifetime language-lawyer

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

std :: vector <T>的比较运算符无法找到T的比较运算符

以下非常简单的代码将无法编译

#include <vector>
#include <string>


namespace Foobar {
    struct Test {
        std::string f;
        std::uint16_t uuid;
    };
}

bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
    return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
}


int main(){

    std::vector<Foobar::Test> a;
    std::vector<Foobar::Test> b;

    if(a==b){

    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/g/zn6UgJ

不会编译我的任何编译器.

而以下

#include <vector>
#include <string>


namespace Foobar {
    struct Test {
        std::string f;
        std::uint16_t uuid;
    };

    bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
        return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
    }
}



int …
Run Code Online (Sandbox Code Playgroud)

c++ dependent-name template-function name-lookup argument-dependent-lookup

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

使派生的C++类"最终"改变ABI吗?

我很好奇,如果标记现有的派生C++类final以允许去虚拟化优化将在使用C++ 11时改变ABI.我的期望是,它应该有没有影响,因为我认为这主要是提示编译器有关它如何能够优化虚函数,因此我看不到任何方式,它会改变结构或V表的大小,但也许我错过了什么?

我知道这里更改API,以便从这个派生类进一步派生的代码将不再起作用,但我只关注这个特殊情况下的ABI.

c++ virtual-functions abi vtable c++11

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

退出状态是否可观察到行为?

C 2018 5.1.2.3 6说:

符合实施的最低要求是:

  • 根据抽象机器的规则严格评估对易失性对象的访问.

  • 在程序终止时,写入文件的所有数据应与根据抽象语义执行程序的结果相同.

  • 交互设备的输入和输出动态应按照7.21.3的规定进行.这些要求的目的是尽快出现无缓冲或行缓冲输出,以确保在程序等待输入之前实际出现提示消息.

这是该程序的可观察行为.

从表面上看,这不包括程序的退出状态.

关于exit(status),7.22.4.4 5说:

最后,控制权返回给主机环境.如果值status为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式.如果值statusEXIT_FAILURE,地位的实现定义的形式成功终止返回.否则返回的状态是实现定义的.

标准没有告诉我们这是可观察行为的一部分.当然,这种exit行为纯粹是C的抽象机器的描述是没有意义的; 除非在环境中可观察到,否则向环境返回值没有意义.所以我的问题不在于退出状态是否可观察到这是否是C标准对可观察行为的定义中的缺陷.或者标准中的其他地方是否有适用的文字?

c program-entry-point exit-code exit language-lawyer

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