我正在学习c ++.现在我明白派生类不能访问它的基类私有成员,但为什么一个模板化的人可以?
比如像这样的东西工作正常:
class base {
static int x;
};
template<typename T>
class derived: public base{
T t;
public:
void setx(int i) {x=i;}
int getx(){return x;}
};
Run Code Online (Sandbox Code Playgroud)
我在linux上使用gcc 5.4.
如果它具有初始化程序,则可以在不显式说明其大小的情况下声明数组:
// very fine: decltype(nums) is deduced to be int[3]
int nums[] = { 5, 4, 3 };
Run Code Online (Sandbox Code Playgroud)
但是,当在类中声明数组时,这是行不通的:
class dummy_class
{
// incomplete type is not allowed (VS 2019 c++17)
int nums[] = { 5, 4, 3 };
};
Run Code Online (Sandbox Code Playgroud)
为什么会这样呢?
考虑以下代码:
struct A
{
// No data members
//...
};
template<typename T, size_t N>
struct B : A
{
T data[N];
}
Run Code Online (Sandbox Code Playgroud)
这就是你必须如何初始化 B:B<int, 3> b = { {}, {1, 2, 3} };
我想避免基类不必要的空 {}。Jarod42 here提出了一个解决方案,但是,它不适用于元素默认初始化:B<int, 3> b = {1, 2, 3};很好,但B<int, 3> b = {1};不是:b.data[1]并且b.data[2]没有默认初始化为 0,并且会发生编译器错误。有什么方法(或者 C++20 会有)从构造中“隐藏”基类?
我想知道关于下面这段代码的标准是什么.可以string临时对象的析构函数调用之前执行printPointer?
ps VS2010编译器不会抱怨此代码并且工作正常.
void printPointer(const string* pointer)
{
cout << *pointer << endl;
}
const string* func(const string& s1)
{
return &s1;
}
int main()
{
printPointer(func("Hello, World!!!"));
}
Run Code Online (Sandbox Code Playgroud) 我有一个类Item,它定义了自己的operator new和operator delete,如下所示:
class Item
{
public:
Item(const std::string &s):msg(s)
{
std::cout<<"Ctor: "<<msg<<std::endl;
}
static void* operator new(size_t size, int ID, const std::string &extra)
{
std::cout<<"My Operator New. ID/extra: "<<ID<<"/"<<extra<<std::endl;
return ::operator new(size);
}
static void operator delete(void* p)
{
std::cout<<"My Operator Delete"<<std::endl;
return;
}
~Item()
{
std::cout<<"Destructor: "<<msg<<std::endl;
}
void Print()
{
std::cout<<"Item::msg: "<<msg<<std::endl;
}
private:
std::string msg;
};
Run Code Online (Sandbox Code Playgroud)
我使用placement new创建了这种类型的对象,然后删除如下:
int main()
{
Item *pI=new(1,"haha")Item("AC Milan");
std::cout<<"before delete"<<std::endl;
delete pI;
std::cout<<"after delete"<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是: …
我用3个编译器测试了以下代码,得到了3个不同的结果:错误,警告和确定.
哪个编译器正确?我知道这是指针类型和bool.之间的微不足道的转换.但那是什么std::nullptr_t和bool?
(最后,Clang和MSVC对代码都很好.Clang以积极的方式更加冗长.)
struct Thing
{
Thing(bool) {}
};
void addThing(const Thing&){}
int main()
{
addThing(nullptr); // warning or error on this line
}
Run Code Online (Sandbox Code Playgroud) 所以我在这里读到:https://stackoverflow.com/a/598150/2642059这是非法的:
foo(i++, i++);
Run Code Online (Sandbox Code Playgroud)
但我相信这是因为没有强制序列,我理解的是初始化列表的情况.这个法律代码也是如此吗?
const int foo[] = { i++, i++ };
Run Code Online (Sandbox Code Playgroud) Visual C++ 2017和gcc 5.4 在此代码段中产生但不是conversion from 'const unsigned char' to 'const float' requires a narrowing conversion警告:Line BLine A
#include <iostream>
int main() {
const unsigned char p = 13;
const float q = p; // Line A
std::cout << q << '\n';
const unsigned char c[3] = {0, 1, 255};
const float f[3] = {c[2], c[0], c[1]}; // Line B
for (auto x:f)
std::cout << x << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这个警告有效吗?为什么Line B治疗不同于Line A?
例如,如果我有
#include <type_traits>
struct OwnershipReceiver
{
template <typename T,
class = typename std::enable_if
<
!std::is_lvalue_reference<T>::value
>::type
>
void receive_ownership(T&& t)
{
// taking file descriptor of t, and clear t
}
};
Run Code Online (Sandbox Code Playgroud)
海报使用!std::is_lvalue_reference而不是立即更明显std::is_rvalue_reference.我已经在我自己的代码中验证了这一点,前者有效,后者没有.
任何人都可以解释为什么明显不起作用?
对于函数参数,可以将 r 值绑定到 l 值常量引用。但是,这似乎不适用于特殊成员函数,如 C++11 和 C++14 中的复制构造函数和复制赋值运算符。这有什么动机吗?
使用 C++17 时,可以从 r 值复制构造,但不能复制赋值。是否有动机为什么这里只更改了复制构造函数的行为?
所有这些都在以下示例中进行了演示:
struct B {
B() = default;
B(B const&) = default;
B(B&&) = delete;
B& operator=(B const&) = default;
B& operator=(B&&) = delete;
};
void bar(B const &) {}
int main() {
bar(B{}); // does work
B(B{}); // only works in C++17
B b{};
b = B{}; // doesn't work
}
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++11 ×4
c++17 ×2
destructor ×2
gcc ×2
templates ×2
arguments ×1
arrays ×1
c++20 ×1
enable-if ×1
gcc-warning ×1
inheritance ×1
rvalue ×1
sequencing ×1
temporary ×1
visual-c++ ×1