假设我声明了这个函数:
class A
{
...
public:
void setRect(Rect & rct);
...
}
Run Code Online (Sandbox Code Playgroud)
该成员setRect被称为这样.
A a;
a.setRect(Some_Func_Return_A_Rect_Object());
Run Code Online (Sandbox Code Playgroud)
gcc编译器抱怨找不到匹配的函数A :: setRect(Rect)
如果我这样打电话,那很好:
A a;
Rect rct = Some_Func_Return_A_Rect_Object();
a.setRect(rct);
Run Code Online (Sandbox Code Playgroud)
标准是否对此有所说明?GCC只是不允许第一种调用setRect()函数的方式?
我有以下代码:
struct Iface
{
virtual int Read() = 0;
int Read(int x) {
return Read() + x;
}
};
template <typename Impl>
struct Crtp : public Iface
{
virtual int Read() {
return static_cast<Impl&>(*this).ReadImpl();
}
//using Iface::Read;
};
struct IfaceImpl : public Crtp<IfaceImpl>
{
int ReadImpl() {
return 42;
}
};
int main()
{
IfaceImpl impl;
impl.Read(24); // compilation error
Iface& iface = impl;
iface.Read(24); // always compiles successfully
}
Run Code Online (Sandbox Code Playgroud)
msvc,gcc和clang都拒绝这个代码,他们找不到方法 Read(int x)
但是如果我using Iface::Read在Crtp我的代码中取消注释成功编译.
请注意,如果我参考Iface,我可以打电话 …
假设模板功能
template<typename T>
T foo(){
// ...
// Error occured
if(error)
return 0;
// ...
}
Run Code Online (Sandbox Code Playgroud)
这应该返回0,0.0f,nullptr,...取决于类型T,当错误发生.
如何获取0未知模板类型?在C#中你可以写default(T)这个来做.
如何在C++中执行此操作?
这是代码:
class TestA
{
protected:
int test=12;
public:
TestA() {
cout << "test a: " << test << endl;
}
~TestA() {
}
};
class TestB : public TestA
{
public:
TestB(TestA *testA) {
cout << "test b: " << testA->test;
}
~TestB() {
}
};
int main ()
{
TestA *pTestA=new TestA();
TestB *pTestB=new TestB(pTestA);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试protected使用指向TestA类型对象的指针(因此,实例TestA)来访问成员.TestB也来源于TestA
为什么我无法访问它?它只能在我需要它的类中"访问"吗?不在外面使用指针/直接声明?
在"C++编程语言"第四版 - 第23.4.7章"朋友"中,我找到了以下示例(我稍微修改了它以仅显示相关部分):
template<typename T>
class Vector {
public:
friend Vector operator*<>(const Vector& v, int f);
^^ ~~~~ ?
};
template<typename T>
Vector<T> operator*(const Vector<T>& v, int f) {
return v;
}
Run Code Online (Sandbox Code Playgroud)
我试图编译它,但我得到以下错误(clang):
main.cpp:8:20: error: friends can only be classes or functions
friend Vector operator*<>(const Vector& v, int f);
^
main.cpp:8:29: error: expected ';' at end of declaration list
friend Vector operator*<>(const Vector& v, int f);
^
;
2 errors generated.
Run Code Online (Sandbox Code Playgroud)
书解释说:
需要友元函数名称后面的<>来表明朋友是模板函数.如果没有<>,则假定为非模板函数.
这就是全部.
如果没有<>此代码编译,但在使用operator*时(例如Vector<int> v; v*12; …
#include <iostream>
const char* fun()
{
const char* x = "abc";
std::cout << "x = " << x << "\n";
return x;
}
int main(int arc, char** argv)
{
const char* y = fun();
std::cout << "y = " << y << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在我的机器上运行它给出:
x = abc
y = abc
Run Code Online (Sandbox Code Playgroud)
在fun(),x(一个局部变量)被分配字面创建本地一个字符串的地址,然而,当该函数返回时,该数据指向y是作为通过指向同一x即使x超出范围.
有人可以详细解释这里发生了什么吗?
请看以下代码:
class Foo
{
public:
Foo(){}
explicit Foo(const Foo &){}
};
int main()
{
Foo foo1;
Foo foo2(foo1);
Foo foo3 = foo1; //can not compile
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么Foo foo3 = foo1;无法编译,两个复制构造函数调用之间有什么区别?
ps:我的编译器工具是GCC4.8.2
当我将a unique_ptr<>移入引发的函数中时,move -from指针不为空。这是正常现象吗?
这是两个显示该行为的测试程序。我可以在类的析构函数中观察到唯一的指针:
#include <memory>
#include <iostream>
void f(std::unique_ptr<int> &&) { throw "fail"; }
struct except_move_tester
{
std::unique_ptr<int> x;
except_move_tester()
: x(std::make_unique<int>(0))
{}
~except_move_tester() { std::cout << "x at destructor: " << x.get() << std::endl; }
void g()
{
std::cout << "x at g: " << x.get() << std::endl;
f(std::move(x));
}
};
int main()
{
try {
except_move_tester t;
t.g();
} catch (...) {}
}
Run Code Online (Sandbox Code Playgroud)
运行时给出的输出:
x at g: 0x7f818b402ac0
x at destructor: 0x7f818b402ac0
Run Code Online (Sandbox Code Playgroud)
如果我按如下方式修改上面的清单(只是在函数调用的位置添加了一个临时名称),那么我通常会期望得到异常安全行为:
#include <memory>
#include …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 C++ 模板创建与 Visual Studio _countof 宏等效的内容。以下是我建议的定义:
\n\ntemplate<typename T, size_t N>\ninline constexpr size_t countof(T const (&array)[N]) {\n return N;\n}\ntemplate<typename T, typename U, size_t N>\ninline constexpr size_t countof(T const (U::&array)[N]) {\n return N;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n上面的第二个声明是尝试修复以下代码,该代码在 g++ 9 中生成编译时错误,并显示消息:“错误:无效使用非静态数据成员 \xe2\x80\x98foo::bar\xe2\ x80\x99":
\n\nstruct foo {\n int const bar[4];\n static_assert(countof(bar) == 4);\n};\nRun Code Online (Sandbox Code Playgroud)\n\n但是,当我添加第二个定义并将断言更改为 use 时foo::bar,g++ 生成错误:“错误:\xe2\x80\x98template constexpr const size_t countof\xe2\x80\x99 与先前的声明冲突”。
我可以更改代码以使用指向成员的指针(而不是对成员的引用),但这似乎是不必要的。有谁知道一种方法来制作countof仅在传递数组时才编译的版本,并且以合理的方式适用于自由数组和成员变量数组?
我正在读一本关于用C ++实现的数据结构的书,我不明白代码片段吗?它是向量类的一部分
void push_back(object &&x) {
//do something
objects[size++] = std::move(x);
}
Run Code Online (Sandbox Code Playgroud)
我知道std::move返回对象的右值引用,但是push_back成员函数已经具有右值引用x作为参数,std::move这里不是不必要的吗?
另一个问题是,如果我们有一个类对象的右值引用,std::move如果要调用move而不是copy right 还是需要在其成员上使用它?像下面的代码:
A& operator=(A&& other) {
member = std::move(other.member);
return *this;
}
Run Code Online (Sandbox Code Playgroud)