在设计解决方案时,有时为原始数据类型提供包装类可能很方便.考虑一个表示数值的类,无论是a double,a float还是a int.
class Number {
private:
double val;
public:
Number(int n) : val(n) { }
Number(float n) : val(n) { }
Number(double n) : val(n) { }
// Assume copy constructors and assignment operators exist
Number& add(const Number& other) {
val += other.val;
return *this;
}
int to_int() const { return (int) val; }
float to_float() const { return (float) val; }
double to_double() const { return val; }
};
Run Code Online (Sandbox Code Playgroud)
现在假设我有这样的功能:
void advanced_increment(Number& n) { …Run Code Online (Sandbox Code Playgroud) 假设我正在编写一个简单的缓冲类.此缓冲区将充当标准C对象数组的简单包装器.它也应该是向后兼容的,可以使用简单数组作为输入的现有函数.
这里的目标是使这个缓冲区在速度和内存使用方面都很有效.由于堆栈分配总是比堆快,我想将堆栈上的所有内容分配到某个阈值,如果它变大,则在堆上重新分配.如何有效地完成这项工作?
我研究过,显然std :: string做了类似的事情.我只是不确定如何.我所拥有的最接近的解决方案是(伪代码,未编译):
template <typename T, int MinSize>
class Buffer
{
public:
void Push(const T& t)
{
++_size;
if (_size > MinSize && _heap == NULL)
{
// allocate _heap and copy contents from stack
// _stack is unused and wasted memory
}
else if (_heap != NULL)
{
// we already allocated _heap, append to it, re-allocate if needed
}
else
{
// still got room on stack, append to _stack
}
}
void Pop()
{
--_size; …Run Code Online (Sandbox Code Playgroud) 这是2011年这个问题的扩展: 基于范围的for循环和ADL
使用Visual Studio 2015,我无法使用Argument Dependent Lookup(ADL)为自定义容器创建基于范围的for循环.
我在下面用一个自定义容器做了一个非常简单的测试用例:
#include <vector>
namespace Foo
{
template <typename T>
class Container
{
public:
std::vector<T> values;
};
}
template <typename T>
typename std::vector<T>::iterator begin(Foo::Container<T>& foo)
{
return foo.values.begin();
}
template <typename T>
typename std::vector<T>::iterator end(Foo::Container<T>& foo)
{
return foo.values.end();
}
Run Code Online (Sandbox Code Playgroud)
使用此容器和ADL,以下测试编译完全正常:
int main(int argc, char* argv[])
{
Foo::Container<int> values;
for (auto it = begin(values); it != end(values); ++it)
{
...
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如它应该.我不确定ADL是否在这里使用,但无论如何,这都是有道理的.从MSDN文档中,我们有:
请记住有关基于范围的这些事实:
自动识别数组.
识别具有.begin()和.end()的容器.
使用依赖于参数的查找begin()和end()用于其他任何事情.
根据我对ADL的理解以及上面的文档,还应该编译以下内容:
int main(int …Run Code Online (Sandbox Code Playgroud) 我有一个模板基类,它有一个构造函数,用于从该类的任何其他模板实例化转换,如下所示:
template <class T>
class FooBase
{
public:
FooBase()
{
}
template <class U>
FooBase(const FooBase<U>& other)
{
std::cout << "FooBase<U>" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
注意没有定义复制构造函数.
然后我有一个派生模板类,它有一个复制构造函数,以及用于转换的构造函数:
template <class T>
class Foo : public FooBase<T>
{
public:
Foo()
{
}
Foo(const Foo& other) :
FooBase<T>(other)
{
}
template <class U>
Foo(const Foo<U>& other) :
FooBase<T>(other)
{
}
};
Run Code Online (Sandbox Code Playgroud)
因为FooBase没有复制构造函数,所以这会导致FooBase<T>(other)调用编译器生成的复制构造函数.这意味着如果我运行这个:
int main()
{
Foo<int> a;
Foo<int> b(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
什么时候输出都没有FooBase<U>.
当然,我可以尝试通过创建一个拷贝构造函数来解决问题FooBase …
请考虑以下代码:
class Foo
{
...
};
template <class T>
class Bar
{
T t;
};
Run Code Online (Sandbox Code Playgroud)
是否保证sizeof(Foo) == sizeof(Bar<Foo>)始终评估true任何标准C++编译器?
是否存在上述情况永远不会成立的情况?
我有一个函数,它接受std::function一个参数.但是,我想确保传入的函数不允许修改传递给它的参数.
这是函数的简单版本(注意T可以,通常是参考):
template <class T>
void Bar(std::function<void(std::add_const_t<T>)> func)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
用法不好:
Bar<int&>([](int&) { /* Do nasty stuff! */ }); /* A-OK! */
Run Code Online (Sandbox Code Playgroud)
我想禁止这种用法,但是这段代码编写得非常好,即使我觉得它不应该.
有趣的是,如果我摆脱模板参数,即:
void Bar(std::function<void(const int&)> func)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后,这种用法不会编译(因为它不应该):
Bar([](int&) { /* Do nasty stuff! */ }); /* Error C2664 */
Run Code Online (Sandbox Code Playgroud)
如何强制执行此操作并仍然保留模板参数?
我对iOS SDK比较陌生,而且我正在遇到一个关于我正在处理的应用程序的设备键盘位置和方向的一个非常奇怪的问题.问题是,如果在用户多任务或应用程序进入后台时键盘处于打开状态,则在用户返回应用程序后,键盘将被移位(UIKeyboardWillChangeFrameNotification被抬起),但方向和位置不正确.
有时键盘也会完全脱离屏幕,这是完全不受欢迎的行为.
我的问题是:
键盘的位置和方向取决于什么?它是如何由iOS控制的?
有没有办法检测键盘何时在屏幕外显示,无论设备类型和屏幕尺寸如何?我认为跟踪UIKeyboardWillChangeFrameNotification或者是可行的UIKeyboardWillShowNotification.
如何在显示键盘之前重置/设置键盘的位置和方向?这甚至可能吗?
我在C++中看到了很多代码,例如下面的例子,它通常被推荐为一个约定:
class Foo
{
public:
Foo()
{
bar = new int[100];
size = 100;
}
// ... copy/assignment stuff ...
~Foo()
{
if (bar) // <--- needed?
{
delete[] bar;
bar = nullptr; // <--- needed?
}
size = 0; // <--- needed?
}
private:
int* bar;
int size;
};
Run Code Online (Sandbox Code Playgroud)
对我来说,这三条语句if (bar) { ... },bar = nullptr;以及size = 0;是多余的,原因有二:
delete nullptr; 是完全安全的,它什么都不做.bar,以nullptr和size为0.这些理由是否正确?这些陈述真的是多余的吗?如果是这样,为什么人们继续使用并建议它们?我希望看到一些可以通过保持这一惯例来解决的潜在问题.
呈现原始 HTML 字符串的最简单方法是什么,例如:
<b>Hello World</b>
Run Code Online (Sandbox Code Playgroud)
放入标准 Node.js 缓冲区作为 PNG 图像?
我一直在 npm 上到处搜索可以让我这样做的模块,但我一直找不到。它们似乎都直接渲染到文件中。
我在一个子类中重载operator new/delete,我注意到一个对我来说似乎很奇怪的行为.看看下面的示例代码:
#include <stdlib.h>
#include <stdio.h>
class Base
{
public:
virtual ~Base()
{
}
};
class Derived : public Base
{
public:
void* operator new(unsigned int size, int capacity)
{
printf("> new(unsigned int, int)\n");
return malloc(sizeof(Derived));
}
void operator delete(void* ptr, int)
{
printf("> delete(void*, int)\n");
free(ptr);
}
void operator delete(void* ptr)
{
printf("> delete(void*)\n");
free(ptr);
}
};
int main(int argc, char** argv)
{
Base* base = new (0) Derived();
delete base;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用Visual Studio 2010编译时,此代码生成以下输出:
> new(unsigned …Run Code Online (Sandbox Code Playgroud) c++ ×8
inheritance ×2
templates ×2
const ×1
constructor ×1
conventions ×1
destructor ×1
html ×1
ios ×1
ipad ×1
iphone ×1
lambda ×1
new-operator ×1
node.js ×1
npm ×1
primitive ×1
sizeof ×1
uikeyboard ×1
visual-c++ ×1
wrapper ×1