假设我有以下功能:
void foo(std::vector<int> vec, int n);
Run Code Online (Sandbox Code Playgroud)
如果我这样调用函数:
std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
foo(std::move(numbers), numbers[0]);
Run Code Online (Sandbox Code Playgroud)
在绑定参数之前是否完全评估了所有参数?在这种情况下,它std::move
是无害的,因为它只是产生一个xvalue指的numbers
.或者,一旦评估,每个单独的参数是否可以立即绑定到其参数?在这种情况下,numbers[0]
可能会导致未定义的行为,因为numbers
可能已经被移入vec
.
我试图创建一个使用智能指针的自定义内存分配器.我没有发布代码,因为它太大而且没有添加太多信息.然后我用一个测试它std::vector
.它在Xcode上运行得非常好.但是当我尝试在Visual Studio 12(2013)中构建相同的代码时,构建失败并出现以下错误:
... vector(873):错误C2660:'
std::_Wrap_alloc< my_allocator< int > >::construct
':函数不带2个参数
问题出在push_back方法中:
void push_back(value_type&& _Val)
{
....
this->_Getal().construct(this->_Mylast,
_STD forward<value_type>(this->_Myfirst[_Idx]));
....
}
Run Code Online (Sandbox Code Playgroud)
错误消息有点令人困惑.真正的问题是this->_Mylast
类型my_allocator< int >::pointer
,它是一个智能指针,而构造方法是期望的int*
.
所以,问题很简单:自定义内存分配器中使用的指针类型有哪些要求?应该X::pointer
可以转换为原始指针?如果是的话,它会让它们变得毫无用处.
实际上我希望这行代码看起来像:
this->_Getal().construct(addressof(*(this->_Mylast)),
_STD forward<value_type>(this->_Myfirst[_Idx]));
Run Code Online (Sandbox Code Playgroud)
让我们尝试在C++标准中找到答案,其中说:
[17.6.3.5-5]分配器类型X应满足CopyConstructible(17.6.3.1)的要求.的
X::pointer
,X::const_pointer
,X::void_pointer
,和X::const_void_pointer
类型应满足NullablePointer(17.6.3.3)的要求.对这些类型的构造函数,比较运算符,复制操作,移动操作或交换操作不应通过异常退出.X::pointer
并且X::const_pointer
还应满足随机访问迭代器的要求(24.2)
如果我们看看NullablePointer reqs,他们会添加一些其他要求:
[17.6.3.3] NullablePointer类型是一种类似指针的类型,支持空值.如果符合以下条件,则类型P满足NullablePointer的要求:
(1.1) - P满足EqualityComparable,DefaultConstructible,CopyConstructible,CopyAssignable和Destructible的要求......
如果我检查随机访问迭代器的要求,我也没有找到任何明确提到它的转换为原始指针.但是在很少的地方使用了方法addressof
(例如24.2.1-5).
此外,它并不是Microsoft std::vector
实现中唯一X::pointer
与假定原始指针相等的地方.我想知道,我错过了什么?
编辑:我将在这里添加一段my_allocator deffinition:
class my_allocator
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t …
Run Code Online (Sandbox Code Playgroud) C++ 03标准规定§1.8[intro.object]/4:
如果完整对象,数据成员(9.2)或数组元素属于类类型,则其类型被视为派生类最多的类,以区别于任何基类子对象的类类型; 最派生类类型的对象称为最派生对象.
任何人都可以对"最衍生的对象"有所了解吗?一些例子将非常感谢.
这个问题与c ++有关
有一个库声明了一个名为Solver <TS,FS>的类.求解器是另一个类域的成员(由我编写)
现在有很多域都有成员"int region"
我想要做的是取决于region的值,我想让求解器接受TS和FS的不同参数.我在考虑一些事情
template<int region>
struct Decider
{
if(region==1)
{
typedef TSA TS;
typedef FSA FS;
}
else
if(region==2)
{
typedef TSB TS;
typedef FSB FS;
}
}
Run Code Online (Sandbox Code Playgroud)
然后用它作为
Decider<region>::TS
Decider<region>::FS
Run Code Online (Sandbox Code Playgroud)
但是,这里由于if的范围,我猜结构是没用的.但是,我无法想到一个更好的方法来做到这一点.有什么建议?
所有不同的TS和FS都具有相同的接口.所以我不必担心内部代码.
因此,当您在编译C++时添加优化标志时,它运行得更快,但这是如何工作的?有人能解释一下装配中究竟发生了什么吗?
我正在尝试使用模板特化来实现带有句柄的模板函数.
以下代码在gcc中给出了"非命名空间作用域中的显式特化":
template <typename T>
static T safeGuiCall(boost::function<T ()> _f)
{
if (_f.empty())
throw GuiException("Function pointer empty");
{
ThreadGuard g;
T ret = _f();
return ret;
}
}
// template specialization for functions wit no return value
template <>
static void safeGuiCall<void>(boost::function<void ()> _f)
{
if (_f.empty())
throw GuiException("Function pointer empty");
{
ThreadGuard g;
_f();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试将它移出类(该类没有模板化)并进入命名空间,但后来我得到错误"显式专门化不能有一个存储类".我已经阅读了很多关于此的讨论,但人们似乎并不同意如何专门化功能模板.有任何想法吗?
我不敢相信gcc不会接受以下代码...请告诉我,如果从基本模板访问内部类是真的不可能或我错过了什么?
template <class T> class BaseClass
{
public:
struct MyStruct
{
T *data;
};
};
template <class T> class ChildClass : public BaseClass <T>
{
public:
void problem()
{
MyStruct ms1; //error: 'MyStruct' was not declared in this scope
::MyStruct ms2; //error: '::MyStruct' has not been declared
BaseClass<T>::MyStruct ms3; //error: expected `;' before 'ms3'
}
};
Run Code Online (Sandbox Code Playgroud) 通过这个示例程序,我在g ++和clang中观察到了不同的行为
foo.h中:
#include <iostream>
namespace Bar
{
class Foo
{
public:
Foo(int x) : _x(x)
{}
int x() const
{
return _x;
}
private:
int _x;
};
}
std::ostream& operator <<(std::ostream& os, const Bar::Foo* foo);
Run Code Online (Sandbox Code Playgroud)
Foo.cpp中
#include <Foo.h>
using namespace std;
ostream& operator <<(ostream& os, const Bar::Foo* foo)
{
return os << foo->x();
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <iostream>
using namespace std;
template<typename T>
void print(const T& t)
{
cout << t << endl;
}
#include <Foo.h>
int main(int argc, char** …
Run Code Online (Sandbox Code Playgroud) 可能重复:
模板中的类使用不完整
我有一个困扰我几个小时的问题.
最初我认为类型必须在实例化时完成,但我尝试的所有编译器都接受该类型在那时仍然是不完整的,只要它在翻译单元中的任何地方定义.
为了说明它,问题是关于这个简单程序的正确性:
template <typename T>
int size() {
return sizeof(T); // T is required to be complete in this expression
}
class test; // test is declared, but incomplete
int main() {
size<test>();
}
// [1] point of instantiation of size<test>()
class test {}; // Definition of test, now it is complete
Run Code Online (Sandbox Code Playgroud)
根据§14.6.4.1/ 1,实例化的点size<test>
是标记为[1]的行,此时类型test
仍然不完整.如果我们试图在sizeof(test)
那里执行操作,编译器将无法告诉我们类型是不完整的.然而,调用一个模板,其中执行相同精确操作的类型在g ++,clang ++,comeau和Visual Studio 2010中编译.
以前的代码是否真的正确?如果在同一个翻译单元的任何地方完成,那么在标准中它支持用作模板参数的类型是否完整?或者什么时候必须完成?
我有一个类OpenGLRenderer
具有类成员mMemoryAllocator
这是一个std::shared_ptr<MemoryAllocator>
.我将内存分配器保留在shared_ptr中的原因是因为即使shared_ptr<Texture>
返回的下面的内容超过了它的创建者OpenGLRenderer
,MemoryAllocator
如果我按值捕获它,实例仍然有效,因为它会增加引用计数:
std::shared_ptr<Texture> OpenGLRenderer::CreateTexture(TextureType textureType, const std::vector<uint8_t>& textureData, uint32_t textureWidth, uint32_t textureHeight, TextureFormat textureFormat)
{
return std::shared_ptr<Texture>(mMemoryAllocator->AllocateObject<Texture>(
textureData, textureWidth, textureHeight,
textureFormat, textureType, mLogger),
[=](Texture* texture) {
mMemoryAllocator
->DeallocateObject<Texture>(texture);
});
}
Run Code Online (Sandbox Code Playgroud)
......但是,它不起作用.如果OpenGLRenderer
超出范围之前std::shared_ptr<Texture>
,std::shared_ptr<MemoryAllocator>
则会变得损坏,因此lambda表达式变得疯狂.我做错了什么?
c++ ×10
templates ×4
c++11 ×3
boost ×1
class ×1
evaluation ×1
inheritance ×1
lambda ×1
name-lookup ×1
pointers ×1
type-traits ×1
typedef ×1