我有这样的代码:
template <typename T, typename U> struct MyStruct {
T aType;
U anotherType;
};
class IWantToBeFriendsWithMyStruct
{
friend struct MyStruct; //what is the correct syntax here ?
};
Run Code Online (Sandbox Code Playgroud)
为模板提供友谊的正确语法是什么?
我正在阅读一本名为"C++编码标准"的书作者:Herb Sutter,Andrei Alexandrescu和本书第42章就是一个例子:(章节很短,所以我正在冒昧并粘贴它的一部分)
考虑:
class Socket {
public:
// … constructor that opens handle_, destructor that closes handle_, etc. …
int GetHandle() const {return handle_;} // avoid this - (1) <-why this is bad code?
// and why there is a comment to avoid such code??
private:
int handle_; // perhaps an OS resource handle
};
Run Code Online (Sandbox Code Playgroud)
数据隐藏是一种功能强大的抽象和模块化设备(参见第11和41项).但是隐藏数据然后给它提供句柄是弄巧成拙的,就像锁住房子并将钥匙留在锁中一样.这是因为:
客户端现在有两种实现功能的方法:它们可以使用类的抽象(Socket)或直接操作类所依赖的实现(套接字的C风格句柄).在后一种情况下,对象不知道它认为拥有的资源发生了重大变化.现在,类无法可靠地丰富或修饰功能(例如,代理,记录,收集统计信息),因为客户端可以绕过装饰的受控实现以及它认为正在添加的任何不变量,这使得接下来的错误处理成为可能(参见条款70) .
该类无法更改其抽象的底层实现,因为客户端依赖于它:如果稍后升级Socket以支持具有不同低级原语集的不同协议,则调用获取底层handle_并错误地操作它的代码将是静默的破碎.
该类不能强制执行其不变量,因为调用代码可以改变类不知道的状态:例如,有人可以关闭Socket对象使用的句柄而不通过Socket成员函数,从而使对象无效.
客户端代码可以存储您的类返回的句柄,并在您的类的代码使它们失效后尝试使用它们.
这是本书的摘要:
不要过多地自愿:避免将句柄返回到由您的班级管理的内部数据,因此客户端不会无法控制地修改您的对象认为它拥有的状态.
基本上我要求的是:
为什么标记为(1)的行被列为坏代码的示例(我一直认为返回指针或引用是一个坏主意,但按值返回是正常的.这里他们说按值返回也是个坏主意?)
是否可能存在'&'缺失,它们的真正含义是不通过引用或指针返回内部数据?
谢谢.
"uint isWidget:1;"中冒号(:)运算符的含义是什么?在Qt?是"uint isWidget:1;" 相当于"uint isWidget(1)"?
Qt中的代码是
QObjectData
{
public:
virtual ~QObjectData() = 0;
QObject *q_ptr;
QObject *parent;
QObjectList children;
uint isWidget : 1;
uint pendTimer : 1;
uint blockSig : 1;
uint wasDeleted : 1;
uint ownObjectName : 1;
uint sendChildEvents : 1;
uint receiveChildEvents : 1;
uint inEventHandler : 1;
uint inThreadChangeEvent : 1;
uint hasGuards : 1; //true iff there is one or more QPointer attached to this object
uint unused : 22;
int postedEvents;
QMetaObject *metaObject; // …Run Code Online (Sandbox Code Playgroud) 我有一个模板类,我有一些专业.
但是下一个专业化就是模板本身.你怎么指定这个:
template<typename T>
class Action
{
public: void doStuff() { std::cout << "Generic\n"; }
}
// A specialization for a person
template<>
class Action<Person>
{
public: void doStuff() { std::cout << "A Person\n";}
}
// I can easily specialize for vectors of a particular type.
// But how do I change the following so that it works with all types of vector.
// Not just `int`
template<>
class Action<std::vector<int> >
{
public: void doStuff() { std::cout << "A Generic …Run Code Online (Sandbox Code Playgroud) c++ templates template-specialization template-meta-programming
我正在使用travis.ci来完成我的git存储库的自动测试版本.
对于linux,他们使用:Ubuntu 12.04
with clang 3.4
根据clang页面,Clang 3.4支持所有C++ 14语言功能(只要你使用-std = c ++ 1y标志).
到目前为止一直这么好:
我还需要使用std::index_sequence<t0,...,tn>哪种库功能N3658不是语言功能.但是我找不到任何关于为clang更新C++标准库的具体文档,以确保支持此功能(它不支持开箱即用).
TestCode:
#include <utility>
int main() {
std::index_sequence<1,2,3,4> seq;
}
Run Code Online (Sandbox Code Playgroud)
TestBuild:
> clang++ -std=c++1y pl.cpp
pl.cpp:3:10: error: no member named 'index_sequence' in namespace 'std'
std::index_sequence<1,2,3,4> seq;
~~~~~^
pl.cpp:3:37: error: use of undeclared identifier 'seq'
std::index_sequence<1,2,3,4> seq;
^
2 errors generated.
Run Code Online (Sandbox Code Playgroud)
基于下面的建议,我尝试使用libc ++.
我确实做错了什么,但我从未尝试过使用替代标准库,所以我不确定这里出了什么问题.将在今晚挖掘.但如果您有任何建议,请发表评论.
> sudo apt-get install -qq libc++1 libc6 libc++-dev
> clang++ -stdlib=libc++ pl.cpp
pl.cpp:1:10: fatal …Run Code Online (Sandbox Code Playgroud) #include <functional>
#include <sys/types.h>
#include <sys/socket.h>
std::function<decltype(::bind)> mockbind = ::bind;
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
上面的代码适用于我编译的大多数平台.但是在使用g ++ - 7的ubuntu 14.04上我收到一个错误:
X.cpp:7:65: error: variable ‘std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind’ has initializer but incomplete type
std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind = ::bind;
^~~~~~~~
Run Code Online (Sandbox Code Playgroud)
现在,如果我手动去改变类型 mockbind
std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind = ::bind;
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,我得到了同样的错误:
现在如果我删除了noexcept
std::function<int(int, const sockaddr*, unsigned int)> mockbind = ::bind;
Run Code Online (Sandbox Code Playgroud)
它按预期编译.
所以问题是我可以应用一些模板代码来删除noexcept返回的类型decltype并使其按预期工作.
是否可以为现有的POD类型元素数组创建类似STL的容器,甚至只是STL样式的迭代器?
例如,假设我有一个int数组.能够直接在此数组上调用某些STL函数(例如find_if,count_if或sort)会很方便.
非解决方案:复制整个数组,甚至只是引用元素.目标是节省内存和时间,同时希望允许使用其他STL算法.
使用带有C++的数据库是一个真正的混乱,当我转移到Java时能够使用统一的系统来抽象整个层(也就是Hibernate),这是令人耳目一新的.
DB有几个C++抽象层,但它们通常是特定于供应商的,只有一个包含真实C API的薄层.有没有人遇到过类似于hibernate for C++的东西,或者知道正在查看这个问题域的组或开源项目.
何时在C++中称为"名称"的"标识符"?我主要读到"名称"一词过于使用而不是"标识符",例如:
struct S { int i };
S thing1;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,是thing1一个名称或IDENTIFER?或者术语"标识符"和"名称"是类似的吗?在C中,在引用对象时是否使用术语"名称"?
我已经在变量中得到错误C2065s,我在类头文件中声明为公共数据成员,一个int和一个指向该int的指针.被标记为错误的代码行只有当我在函数中使用这些变量时 - 在类'构造函数中,它们才能正常运行.
我正在使用Visual Studio 2010 Express编写普通的C++(而不是Visual C++),这里是编译器错误日志的输出:
1>------ Build started: Project: Project 2, Configuration: Debug Win32 ------
1> BaseClassWithPointer.cpp
1>d:\libraries\documents\school\advanced c++\project 2\project 2\baseclasswithpointer.cpp(27): error C2065: 'q' : undeclared identifier
1>d:\libraries\documents\school\advanced c++\project 2\project 2\baseclasswithpointer.cpp(27): error C2541: 'delete' : cannot delete objects that are not pointers
1>d:\libraries\documents\school\advanced c++\project 2\project 2\baseclasswithpointer.cpp(32): error C2065: 'num' : undeclared identifier
1>d:\libraries\documents\school\advanced c++\project 2\project 2\baseclasswithpointer.cpp(33): error C2065: 'q' : undeclared identifier
1>d:\libraries\documents\school\advanced c++\project 2\project 2\baseclasswithpointer.cpp(34): error C2065: 'q' : undeclared identifier
1> Generating Code...
========== Build: …Run Code Online (Sandbox Code Playgroud)