我正在玩下面的代码。
#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同时使用GCC和Clang同意以下输出。
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 中发生了什么变化导致了此输出。究竟是什么标准的变化引发了这种情况?
我正在阅读这个史前元程序示例来检测一个类是否支持成员查找。(或任何其他成员)。
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 天后从头开始写同样的东西,我可能会失败。
原因是我不完全理解这里使用的句法和语言延伸。
有人可以解释以下语法的含义吗?
Check<int Fallback::*, &U::find>* (我知道它试图在这里从 SFIANE …我想用作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)
有人可以解释为什么会出现这种情况吗?
最近我尝试运行以下代码。
#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++ 标准中定义的位置(我搜索过但找不到任何东西)?
假设我们有以下代码片段。
#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仍然相同,如果是,在哪些情况下它们可能不同(例如使用关键字等等)?
我最近在阅读有关虚函数和虚析构函数的文章,提出了以下问题。
例如,我有以下继承链。
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)
我读到基类的虚函数在派生类中默认为隐式虚函数。所以,我认为这同样适用于析构函数。
我想知道,派生类的析构函数是否默认是虚拟的。如果没有,如果您提供一些解释,我会很高兴。
我有这个代码:
#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)
编译器没有给出错误(或警告),为什么?
我正在玩下面的代码。
#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 拒绝它。哪个编译器就在这里,为什么?