小编Dav*_*eas的帖子

参数评估后参数绑定是否排序?

假设我有以下功能:

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.

c++ evaluation parameter-passing move-semantics c++11

13
推荐指数
1
解决办法
209
查看次数

具有自定义指针类型的内存分配器

我试图创建一个使用智能指针的自定义内存分配器.我没有发布代码,因为它太大而且没有添加太多信息.然后我用一个测试它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++ pointers memory-management standard-library c++11

12
推荐指数
1
解决办法
1564
查看次数

"最衍生的对象"是什么意思?

C++ 03标准规定§1.8[intro.object]/4:

如果完整对象,数据成员(9.2)或数组元素属于类类型,则其类型被视为派生类最多的类,以区别于任何基类子对象的类类型; 最派生类类型的对象称为最派生对象.

任何人都可以对"最衍生的对象"有所了解吗?一些例子将非常感谢.

c++

11
推荐指数
1
解决办法
3052
查看次数

在C++中是否可以使用条件typedef?

这个问题与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++ templates typedef type-traits

10
推荐指数
3
解决办法
2621
查看次数

优化代码时,编译器在汇编中做了什么?即-O2标志

因此,当您在编译C++时添加优化标志时,它运行得更快,但这是如何工作的?有人能解释一下装配中究竟发生了什么吗?

c++ compiler-optimization

10
推荐指数
1
解决办法
2664
查看次数

静态成员函数的模板特化; 如何?

我正在尝试使用模板特化来实现带有句柄的模板函数.

以下代码在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)

我已经尝试将它移出类(该类没有模板化)并进入命名空间,但后来我得到错误"显式专门化不能有一个存储类".我已经阅读了很多关于此的讨论,但人们似乎并不同意如何专门化功能模板.有任何想法吗?

c++ templates boost

9
推荐指数
2
解决办法
2万
查看次数

模板继承内部类访问问题

我不敢相信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)

c++ inheritance templates class

9
推荐指数
2
解决办法
2078
查看次数

运算符重载clang ++和g ++不同的输出

通过这个示例程序,我在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)

c++ name-lookup

9
推荐指数
1
解决办法
387
查看次数

如果在需要完整类型的上下文中内部使用,则必须将用作模板参数的类型完整吗?

可能重复:
模板中的类使用不完整

我有一个困扰我几个小时的问题.

最初我认为类型必须在实例化时完成,但我尝试的所有编译器都接受该类型在那时仍然是不完整的,只要它在翻译单元中的任何地方定义.

为了说明它,问题是关于这个简单程序的正确性:

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中编译.

以前的代码是否真的正确?如果在同一个翻译单元的任何地方完成,那么在标准中它支持用作模板参数的类型是否完整?或者什么时候必须完成?

c++ templates

8
推荐指数
1
解决办法
330
查看次数

Lambda捕获shared_ptr成员

我有一个类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++ lambda memory-management smart-pointers c++11

8
推荐指数
1
解决办法
4209
查看次数