javascript

java

python

c#

android

node.js

c++

reactjs

php

html

jquery

css

.net

ios

git

ruby-on-rails

sql

c

string

ruby

c ++-reinterpret_cast创建一个普通的默认可构造的obj

cppreference†指出:

可以通过在任何适当对齐的存储上使用reinterpret_cast创建具有默认构造函数的对象,例如 在分配了std::malloc的内存上。

这意味着以下是定义良好的代码:

struct X { int x; };
alignas(X) char buffer[sizeof(X)];    // (A)
reinterpret_cast<X*>(buffer)->x = 42; // (B)

接下来是三个问题:

  1. 那句话正确吗?
  2. 如果是,什么时候std::malloc的寿命开始? 如果在(B)行上,是否将转换本身视为获取存储? 如果在(A)行上,如果在(A)(B)之间存在一个分支,该分支将有条件地构建X或其他某个吊舱Y,该怎么办?
  3. 在这方面,C ++ 11和C ++ 1z之间有什么变化吗?

†请注意,这是一个旧链接。 措词针对此问题进行了更改。 现在显示为:

但是,与C语言不同,不能通过简单地重新解释适当对齐的存储来创建具有琐碎默认构造函数的对象,例如用std::malloc分配的内存:正式引入新对象并避免潜在的未定义行为时,需要placement-new。

trans by 2020-01-26T22:10:14Z

如何遍历压缩的可变参数模板参数列表?

我试图找到一种方法来遍历一个包可变参数模板参数列表。现在,与所有迭代一样,您需要某种方法来知道打包列表中有多少个参数,更重要的是如何从打包参数列表中单独获取数据。

通常的想法是遍历列表,将int类型的所有数据存储到向量中,将char *类型的所有数据存储到向量中,并将float类型的所有数据存储到向量中。 在此过程中,还需要有一个单独的向量,用于存储参数按顺序进入的各个字符。例如,当您push_back(a_float)时,您还正在执行push_back('f'),它只是存储 一个单独的字符来了解数据的顺序。 我也可以在此处使用std :: string,而只需使用+ =。 该载体仅用作示例。

现在,事物的设计方式是使用宏构造函数本身,尽管有恶意,但仍需要这样做,因为这是一个实验。 因此,使用递归调用几乎是不可能的,因为将容纳所有这些内容的实际实现将在编译时进行扩展。 并且您不能撤消宏。

尽管进行了所有可能的尝试,但我仍然坚持找出如何实际执行此操作。 因此,相反,我使用了一种更复杂的方法,该方法涉及构造一个类型,然后将该类型传递给可变参数模板,将其扩展到向量中,然后简单地对其进行迭代。 但是我不想像这样调用函数:

foo(arg(1), arg(2.0f), arg("three");

因此,真正的问题是如果没有这种方法我该怎么办? 为了让大家更好地了解代码的实际作用,我粘贴了当前正在使用的乐观方法。

struct any {
  void do_i(int   e) { INT    = e; }
  void do_f(float e) { FLOAT  = e; }
  void do_s(char* e) { STRING = e; }

  int   INT;
  float FLOAT;
  char *STRING;
};


template<typename T> struct get        { T      operator()(const any& t) { return T();      } };
template<>           struct get<int>   { int    operator()(const any& t) { return t.INT;    } };
template<>           struct get<float> { float  operator()(const any& t) { return t.FLOAT;  } };
template<>           struct get<char*> { char*  operator()(const any& t) { return t.STRING; } };

#define def(name)                                  \
  template<typename... T>                          \
  auto name (T... argv) -> any {                   \
   std::initializer_list<any> argin = { argv... }; \
    std::vector<any> args = argin;
#define get(name,T)  get<T>()(args[name])
#define end }

any arg(int   a) { any arg; arg.INT    = a; return arg; }
any arg(float f) { any arg; arg.FLOAT  = f; return arg; }
any arg(char* s) { any arg; arg.STRING = s; return arg; }

我知道这很讨厌,但这只是一个纯实验,不会在生产代码中使用。 纯粹是个主意。 可能可以做一个更好的方法。 但是如何使用此系统的一个示例:

def(foo)
  int data = get(0, int);
  std::cout << data << std::endl;
end

看起来很像python。 它也可以使用,但是唯一的问题是如何调用此函数。这里是一个简单的例子:

foo(arg(1000));

我需要构造一个新的任何类型,这是非常美观的,但这并不是说这些宏也不是。 除了要点,我只想选择这样做:     foo(1000);

我知道可以做到的,我只需要某种迭代方法,或更重要的是可以使用打包包装的可变参数模板参数列表的std :: get方法。 我确定可以做到。

另外要注意的是,我很清楚这并不完全是类型友好的,因为我只支持int,float,char *,这对我来说还可以。 我不需要其他任何东西,我将添加检查以使用type_traits来验证传递的参数确实是正确的参数,如果数据不正确,则会产生编译时错误。 这完全不是问题。 除这些POD类型外,我也不需要任何其他支持。

如果我能得到一些建设性的帮助,而不是反对我纯粹不合逻辑和愚蠢地使用宏和仅POD类型的说法,那将是万分感激的。 我很清楚代码的脆弱程度。 这是merley的实验,以后我可以纠正非POD数据的问题,并使其更加类型安全和可用。

多谢您的谅解,我们期待提供协助。

trans by 2020-01-26T15:31:27Z

C ++-std :: thread-命名您的线程

新的C ++具有这种std :: thread类型。 奇迹般有效。现在,我想给每个线程起一个名称,以便更轻松地进行调试(例如java允许您这样做)。使用pthreads我可以:

pthread_setname_np(pthread_self(), "thread_name");

但是我该如何使用c ++ 0x呢?我知道它在Linux系统上使用pthreads,但是我想使我的应用程序具有可移植性。 有可能吗?

trans by 2020-01-26T13:54:08Z

c ++-从unordered_map获取键和值的列表

vector<string>获得键和值的列表(作为unordered_map<string, double>)的最有效方法是什么?

为了具体起见,假设所讨论的地图是unordered_map<string, double>。然后,我想以vector<string>的形式获取密钥,以vector<double>的形式获取值。

unordered_map<string, double> um;

vector<string> vs = um.enum_keys();
vector<double> vd = um.enum_values(); 

我可以遍历地图并收集结果,但是还有更多内容吗?有效的方法? 有一种也可以用于常规地图的方法会很好,因为我可能会切换到那个。

trans by 2020-01-26T05:12:25Z

如何在C ++中以编程方式确定表达式是右值还是左值?

确定C ++中表达式是右值还是左值的最佳方法是什么? 可能这在实践中没有用,但是由于我正在学习右值和左值,所以我认为最好有一个函数is_lvalue,如果输入中传递的表达式为左值,则返回true,否则返回false。

例:

std::string a("Hello");
is_lvalue(std::string()); // false
is_lvalue(a); // true  
trans by 2020-01-25T23:00:57Z

具有完整C ++ 11支持的Windows C ++编译器(应与Qt配合使用)

哪个C ++编译器当前在Windows平台上具有完整的C ++ 11支持?

Microsoft编译器当前没有完全的C ++ 11支持(并且不会在短期内添加)。
MinGW g ++(来自mingw.org)不支持std::thread。 它也不能编译Qt 4源(在构建QtGuid4.dll时内存不足,已知的解决方法对我不起作用)。
我已经浪费了几天试图在Windows上运行clang的方法,设法对其进行了编译,但是由于它需要libstdc ++(我当时认为还没有移植到Windows平台),所以无法启用c ++ 11支持。 Qt 4也不支持它。

那里还有什么? 我已经为C ++ 03工作了很长时间,我想尝试一下新功能,但是我真的不想要一个不完整支持的工具(在编写C ++ 03时会增加额外的麻烦) 代码),或者在链接库时可能会用完内存(在8GB系统上)。

我正在使用64位Windows 7,尽管具有64位支持会很好,但我对32位应用程序最感兴趣,因此可以选择生成64位可执行文件。

有什么建议么?

trans by 2020-01-25T08:38:12Z

从初始化列表初始化std :: tuple

我想知道元组是否可以通过初始化列表初始化(更准确地说,是通过initializer_lists的initializer_list初始化)? 考虑元组的定义:

typedef std::tuple< std::array<short, 3>,
                    std::array<float, 2>,
                    std::array<unsigned char, 4>,
                    std::array<unsigned char, 4> > vertex;

有什么办法可以做到以下几点:

static vertex const nullvertex = { {{0, 0, 0}},
                                   {{0.0, 0.0}},
                                   {{0, 0, 0, 0}},
                                   {{0, 0, 0, 0}} };

我只想实现与使用struct而不是元组相同的功能(因此只有数组由initializer_list初始化):

static struct vertex {
    std::array<short, 3> m_vertex_coords;
    std::array<float, 2> m_texture_coords;
    std::array<unsigned char, 4> m_color_1;
    std::array<unsigned char, 4> m_color_2;
} const nullvertex = {
    {{0, 0, 0}},
    {{0.0, 0.0}},
    {{0, 0, 0, 0}},
    {{0, 0, 0, 0}}
};

我没有理由必须使用元组,只是想知道。 我问,因为我无法经历由我尝试进行此类元组初始化而产生的g ++模板错误。

@Motti:所以我错过了统一初始化的正确语法-

static vertex const nullvertex = vertex{ {{0, 0, 0}},
                                         {{0.0, 0.0}},
                                         {{0, 0, 0, 0}},
                                         {{0, 0, 0, 0}} };

static vertex const nullvertex{ {{0, 0, 0}},
                                {{0.0, 0.0}},
                                {{0, 0, 0, 0}},
                                {{0, 0, 0, 0}} };

但是似乎所有的麻烦都在于数组,它没有为initializer_list构造函数,而用适当的构造函数包装数组似乎并不是一件容易的事。

trans by 2020-01-25T04:03:19Z

C ++-std :: unique_ptr用于需要C函数

考虑一个C函数,该函数返回必须为opend的东西,例如POSIX的2717570659072345045089。我想在C ++ 11中使用该函数并避免任何泄漏的机会,这是正确的方法吗?

#include <memory>
#include <iostream>
#include <string.h>

int main() {
    char const* t { "Hi stackoverflow!" };
    std::unique_ptr<char, void(*)(void*)>
        t_copy { strdup(t), std::free };

    std::cout << t_copy.get() << " <- this is the copy!" <<std::endl;
}

假设有意义,是否可以对非指针使用类似的模式? 例如,对于POSIX函数open,该函数返回int

trans by 2020-01-25T01:59:03Z

我应该使用shared_ptr还是unique_p

我一直在使用pimpl惯用语制作一些对象,但不确定是否要使用2717437508392059059904或std::shared_ptr

我知道std::shared_ptr的效率更高,但这对我来说不是什么大问题,因为这些对象无论如何都是相对较重的,因此std::shared_ptrstd::unique_ptr的成本相对较小。

我目前正使用std::shared_ptr,因为它具有额外的灵活性。 例如,使用std::shared_ptr使我可以将这些对象存储在哈希图中以便快速访问,同时仍然能够将这些对象的副本返回给调用方(因为我相信任何迭代器或引用都可能很快变得无效)。

但是,这些对象实际上并没有以某种方式被复制,因为更改会影响所有副本,因此我想知道也许使用std::shared_ptr和允许复制是某种反模式或坏事。

它是否正确?

trans by 2020-01-24T23:47:01Z

c ++-将成员函数从基类移动到派生类不会导致程序中断

这个(虚构的)问题最初被形容为一个谜题,隐瞒了   一些可能有助于更快发现问题的细节。 向下滚动   用于较简单的MCVE版本。


原始(a-la拼图)版本

我有一段输出foo()的代码:

#include <iostream>
#include <regex>

using namespace std;

regex sig_regex("[0-9]+");
bool oldmode = false;

template<class T>
struct B
{
    T bitset;

    explicit B(T flags) : bitset(flags) {}

    bool foo(T n, string s)
    {
        return bitset < 32                   // The mouth is not full of teeth
               && 63 > (~n & 255) == oldmode // Fooness holds
               && regex_match(s, sig_regex); // Signature matches
    }
};

template<class T>
struct D : B<T>
{
    D(T flags) : B<T>(flags) {}

};

int main()
{
    D<uint64_t> d(128 | 16 | 1);
    cout << d.foo(7, "123") << endl;
}

但是,当我将函数foo()B移到D时,它开始输出1(证明在Coliru上)。

为什么会这样?


MCVE版本

住在科利鲁

#include <iostream>
#include <bitset>

using namespace std;

template<class T>
struct B
{
    T bitset{0};

    bool foo(int x)
    {
        return bitset < 32 && 63 > (x + 1) == x % 2;
    }
};

template<class T>
struct D : B<T>
{
    bool bar(int x) // This is identical to B<T>::foo()
    {
        return bitset < 32 && 63 > (x + 1) == x % 2;
    }
};

int main()
{
    D<uint64_t> d;
    cout << d.foo(1) << endl; // outputs 1
    cout << d.bar(1) << endl; // outputs 0; So how is bar() different from foo()?
}
trans by 2020-01-24T05:15:44Z

带有和不带有指针d的C ++ 11自动声明

bar1bar2的类型有什么区别?

int foo = 10;
auto bar1 = &foo;
auto *bar2 = &foo;

如果2715781628828848243712和bar2都是int*,在bar2声明中写入指针声明符(*)是否有意义?

trans by 2020-01-23T20:21:49Z

c ++-std :: function的仅移动版本

因为std::function是可复制的,所以该标准要求用于构造它的可调用对象也应该是可复制的:

n337(20.8.11.2.1)

std::function816

要求:std::function必须是CopyConstructible。 对于参数类型ArgTypes和返回类型Rstd::unique_ptr必须是Callable(20.8.11.2)。A的副本构造函数和析构函数不得抛出异常。

这意味着不可能由捕获了仅移动类型(例如std::unique_ptr)的不可复制的绑定对象或lambda形成std::function

对于仅移动可调用对象,似乎可以实现这种仅移动包装器。 是否有std::function的标准库只能移动的等效项,或者是否有解决此问题的常用解决方法?

trans by 2020-01-23T09:05:29Z

为什么在基于范围的初始化程序中使用临时对象会导致崩溃?

为什么以下代码在Visual Studio和GCC上都崩溃?

要使其崩溃,它需要基于范围的for循环,std :: map,std :: string并引用该字符串。 如果我删除其中任何一个,它将起作用。

#include <iostream>
#include <string>
#include <map>
using namespace std;

struct S
{
    map<string, string> m;

    S()
    {
        m["key"] = "b";
    }

    const string &func() const
    {
        return m.find("key")->second;
    }
};

int main()
{
    for (char c : S().func())
        cout << c;

    return 0;
}

Ideone链接:[http://ideone.com/IBmhDH]

trans by 2020-01-23T01:20:52Z

c ++-使用以下方法遍历QMap

我有一个e对象,并且我正在尝试将其内容写入文件。

QMap<QString, QString> extensions;
//.. 

for(auto e : extensions)
{
  fout << e.first << "," << e.second << '\n';
}  

我为什么得到:e

e不是QPair类型的吗?

trans by 2020-01-22T18:54:05Z

c ++-从初始化列表中初始化unique_ptrs的容器在GCC 4.7中失败

我正在尝试以与Bjarne Stroustrup的C ++ 11 FAQ中的示例等效的方式初始化'std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)'

using namespace std;
vector<unique_ptr<string>> vs { new string{"Doug"}, new string{"Adams"} }; // fails
unique_ptr<string> ps { new string{"42"} }; // OK

我看不出为什么该语法会失败。 这种初始化容器的方式有什么问题吗?
编译器错误消息很大; 我找到的相关细分如下:

/usr/lib/gcc-snapshot/lib/gcc/i686-linux-gnu/4.7.0/../../../../include/c++/4.7.0   /bits/stl_construct.h:77:7:错误:没有匹配的函数可以调用   'std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)'

解决此错误的方法是什么?

trans by 2020-01-22T06:55:03Z

循环条件是否基于C ++ 11范围的for循环条件得到评估?

for(auto& entity : memoryManager.getItems()) entity->update(mFrameTime);

如果memoryManager包含1000个项目,则memoryManager.getItems()是被调用1000次还是在循环开始时被调用一次?

编译器是否使用-O2(或-O3)运行任何优化?

memoryManager.getItems()返回std::vector<Entity*>&

trans by 2020-01-22T00:58:53Z

如何使用<system_error>将errno转换为异常

我阅读了有关C ++ 11中新的system_error标头的一系列博客文章,这些文章颇有思想。 它说标题定义了一个error_code873类,该类表示操作(例如系统调用)返回的特定错误值。 它说头定义了errno类,它是一个异常类(继承自error_code),用于包装error_codess。

我想知道的是如何将系统错误从system_error转换为error_code,以便将其抛出。 例如,POSIX errno函数通过返回-1并设置error_code来报告错误,因此,如果我想引发异常,应该如何完成下面的代码?

void x()
{
    fd = open("foo", O_RDWR);
    if (fd == -1)
    {
        throw /* need some code here to make a std::system_error from errno */;
    }
}

我随机尝试:

errno = ENOENT;
throw std::system_error();

但是在调用system_error时所产生的异常不返回任何信息。

我知道我可以做到system_error,但是我想使用新的error_code标头来正确地做到这一点。

有一个system_error的构造函数,它使用一个error_code作为参数,因此,如果我可以将errno转换为error_code,则其余部分应该很明显。

这似乎是一件非常基本的事情,所以我不知道为什么找不到很好的教程。

如果很重要,我在ARM处理器上使用gcc 4.4.5。

trans by 2020-01-21T04:08:00Z

正确使用右值引用作为参数

让我们以以下方法为例:

void Asset::Load( const std::string& path )
{
    // complicated method....
}

此方法的一般用法如下:

Asset exampleAsset;
exampleAsset.Load("image0.png");

由于我们大多数时候都知道Path是一个临时的右值,因此添加此方法的右值版本是否有意义? 如果是这样,这是否是正确的实现?

void Asset::Load( const std::string& path )
{
    // complicated method....
}
void Asset::Load( std::string&& path )
{
     Load(path); // call the above method
}

这是编写方法的右值版本的正确方法吗?

trans by 2020-01-21T04:02:11Z

为什么我们不能自动推导返回类型?

最近,我和一个朋友一起工作,他想使C ++更加Haskell-y,我们想要一个基本上像这样的函数:

auto sum(auto a, auto b) {
    return a + b;
}

显然我不能使用auto作为参数类型,因此我将其更改为:

template<class A, class B>
auto sum(A a, B b) {
    return a + b;
}

但这也不起作用。 我们最终意识到我们需要这样做:

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b) {
    return a + b;
}

所以我的问题是,有什么意义? decltype是否只是重复信息,因为编译器只能查看return语句?

我认为可能需要这样做,因此我们可以仅包含头文件:

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);

...但是我们还是不能使用这样的模板。

我考虑的另一件事是,对于编译器而言,它可能会更容易,但实际上看起来会更难。

案例1:decltype

  • 找出decltype陈述式的类型
  • 找出任何返回值的类型
  • 看看他们是否匹配

情况2:无decltype

  • 找出任何返回值的类型
  • 看看他们是否匹配

因此,考虑到这些因素,decltype的尾随返回类型有什么意义?

trans by 2020-01-20T23:34:07Z

类似于C的构造函数和统一初始化有什么区别?

据我所知,有三种方法可以在C ++中初始化变量。

int x = 0;    // C-like initialization
int x (0);    // Constructor initialization
int x {0};    // Uniform initialization

C ++ 11引入了统一的初始化,以提供更统一的语法来初始化不同类型的变量,而C ++ 03中需要使用不同的语法。

类C,构造函数和统一初始化之间有什么区别? 我是否应该始终使用统一初始化?

trans by 2020-01-20T13:39:47Z

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 下一页 共23页