小编Kar*_*yan的帖子

转换运算符相对于复制构造函数的偏好从 C++14 更改为 C++17?

我正在玩下面的代码。

#include <iostream>

struct To
{
    To() = default;
    To(const struct From&) {std::cout << "Constructor called\n";}
    To(const To&) {std::cout << "Copy constructor called\n";}
};

struct From
{
    operator To(){std::cout << "Conversion called\n"; return To();}
};

int main()
{
    From f;
    To t(f);
    To t1 = f;
    To t2{To(f)};
}
Run Code Online (Sandbox Code Playgroud)

如果我-std=c++14同时使用GCCClang同意以下输出。

Constructor called
Conversion called
Constructor called
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用 进行编译-std=c++17,则两个编译器都同意

Conversion called
Conversion called
Conversion called
Run Code Online (Sandbox Code Playgroud)

我知道将几个预期的输出行减少为输出 3 行是由于复制省略,但我无法弄清楚 C++17 中发生了什么变化导致了此输出。究竟是什么标准的变化引发了这种情况?

c++ conversion-operator language-lawyer c++14 c++17

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

template&lt;typename T, T&gt; 是什么意思?

我正在阅读这个史前元程序示例来检测一个类是否支持成员查找。(或任何其他成员)。

template<typename T>
class DetectFind
{
    struct Fallback { int find; }; 
    struct Derived : T, Fallback { };

    template<typename U, U> struct Check;

    typedef char Yes[1];  
    typedef char No[2]; 

    template<typename U>
    static No& func(Check<int Fallback::*, &U::find>*);

    template<typename U>
    static Yes& func(...);

public:
    typedef DetectFind type;
    enum { value = sizeof(func<Derived>(0)) == sizeof(Yes) };
};

int main()
{
    std::cout << DetectFind<std::vector<int> >::value << std::endl;
    std::cout<< DetectFind<std::set<int> >::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

直觉上我确实理解这背后的目的,但如果有人让我在 10 天后从头开始写同样的东西,我可能会失败。
原因是我不完全理解这里使用的句法和语言延伸。
有人可以解释以下语法的含义吗?

  1. Check<int Fallback::*, &U::find>* (我知道它试图在这里从 SFIANE …

c++ templates member-pointers sfinae

7
推荐指数
2
解决办法
95
查看次数

std::span 作为模板模板参数不能用 clang 编译

我想用作std::span函数的模板模板参数。gcc 似乎接受以下代码,但 clang 拒绝。

#include <iostream>
#include <span>
#include <vector>

std::vector v{1,2,3,4,5,6};

template <template <typename> class S>
S<int> GetSpan()
{
    return v;
}

int main()
{
    auto x = GetSpan<std::span>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会出现这种情况吗?

https://godbolt.org/z/Ks9M5oqKc

c++ templates clang clang++ c++17

7
推荐指数
2
解决办法
242
查看次数

指向成员函数的指针执行虚拟调度?

最近我尝试运行以下代码。

#include <iostream>

class Base
{
public:
    virtual void func()
    {
        std::cout<<"Base called"<<std::endl;
    }
};

class Derived: public Base
{
public:
    virtual void func()  override
    {
        std::cout<<"Derived called"<<std::endl;
    }
};

int main()
{
    void (Base::*func_ptr)()=&Base::func; //Yes, the syntax is very beautiful.
    Base* bptr=new Derived();
    (bptr->*func_ptr)();
}
Run Code Online (Sandbox Code Playgroud)

我的预期输出是Base called. 然而,输出是

Derived called
Run Code Online (Sandbox Code Playgroud)

这让我感到惊讶,因为根据我的理解,func_ptr应该只能看到Base成员(因为据我所知,func_ptr不是通过 访问成员函数_vptr,而是访问函数地址本身。

我想知道,在这种情况下虚拟调度是如何发生的(如何访问虚拟表),以及这种行为在 C++ 标准中定义的位置(我搜索过但找不到任何东西)?

c++ virtual-functions function-pointers member-pointers

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

不同翻译单元中字符串文字的内存地址是否相同?

假设我们有以下代码片段。

#include <iostream>

int main(){
    const char* p1="hello";
    const char* p2="hello";
    std::cout<<p1==p2;
}
Run Code Online (Sandbox Code Playgroud)

输出

1
Run Code Online (Sandbox Code Playgroud)

正如我们所知,p1 和 p2 指向相同的内存地址(如果我错了,请纠正我)。

现在,假设我们在不同的翻译单元中定义了这些指针:

1
Run Code Online (Sandbox Code Playgroud)

我的问题是,指向pA和的内存地址是否pB仍然相同,如果是,在哪些情况下它们可能不同(例如使用关键字等等)?

c++ memory string-literals

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

如果基类析构函数是虚拟的,派生类的析构函数是否默认为虚拟?

我最近在阅读有关虚函数和虚析构函数的文章,提出了以下问题。

例如,我有以下继承链。

class Base
{
public:
    virtual ~Base() // note: virtual
    {
        std::cout << "Calling ~Base()\n";
    }
};
 
class Derived: public Base
{
 
public:
 
    ~Derived() 
    {
        std::cout << "Calling ~Derived()\n";
    }
};
Run Code Online (Sandbox Code Playgroud)

我读到基类的虚函数在派生类中默认为隐式虚函数。所以,我认为这同样适用于析构函数。

我想知道,派生类的析构函数是否默认是虚拟的。如果没有,如果您提供一些解释,我会很高兴。

c++ polymorphism virtual-destructor

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

为什么 C++ 类可以等于一个变量

我有这个代码:

#include <iostream>
using namespace std;

class complex
{
    double re;
    double im;

public:
    complex(): re(0), im(0) {}
    complex(double x) {re = x, im = x;}
    complex(double x, double y) {re=x, im =y;}
    void print() {cout << re << " " << im;}
};

int main()
{
    complex c1;
    double i=2;
    c1 = i;
    c1.print();

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

我的问题是,为什么这一行中的代码会编译。

c1 = i;
Run Code Online (Sandbox Code Playgroud)

编译器没有给出错误(或警告),为什么?

c++

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

在模板化函数中将 std::vector 设置为本地会导致编译失败

我正在玩下面的代码。

#include <iostream>
#include <span>
#include <vector>

std::vector v{1,2,3,4,5,6};

template <template <typename, std::size_t> class S>
S<int, std::dynamic_extent> GetSpan()
{
    return v;
}

int main()
{
    auto x = GetSpan<std::span>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

GCC 和 Clang 都接受了这一点。但是,如果我std::vector在函数中设置 local in GetSpan(),则 i. e

template <template <typename, std::size_t> class S>
S<int, std::dynamic_extent> GetSpan()
{
    std::vector v{1,2,3,4,5,6};
    return v;
}
Run Code Online (Sandbox Code Playgroud)

Clang 仍然接受该代码,但 gcc 拒绝它。哪个编译器就在这里,为什么?

c++ templates language-lawyer c++17

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