小编Leo*_*eon的帖子

如何从 std::string_view 正确创建 std::string?

我有一堂课:

class Symbol_t {
public:
   Symbol_t( const char* rawName ) {
      memcpy( m_V, rawName, 6 * sizeof( char ) );
   };

   string_view strVw() const {
      return string_view( m_V, 6 );
   };

private:
   char m_V[6];

}; // class Symbol_t
Run Code Online (Sandbox Code Playgroud)

并且有一个我无法修改的 lib-func:

extern bool loadData( const string& strSymbol );
Run Code Online (Sandbox Code Playgroud)

如果有局部变量:

Symbol_t   symbol( "123456" );
Run Code Online (Sandbox Code Playgroud)

当我需要调用loadData时,我不敢这样做:

loadData( string( symbol.strVw().begin(), symbol.strVw().end() ) );
Run Code Online (Sandbox Code Playgroud)

我必须这样做:

string_view svwSym = symbol.strVw();
loadData( string( svw.begin(), svw.end() ) );
Run Code Online (Sandbox Code Playgroud)

我的问题:第一种方法正确吗?还是我必须使用第二个?

因为我认为在方法 1 中,我传递给 std::string 的构造函数的迭代器是两个不同的 string_vew 对象,理论上结果是未定义的,即使我们几乎所有的 C++ 编译器都会得到预期的结果。 …

c++ string iterator reference string-view

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

只要进程处于活动状态,const char* 文字字符串是否就持久存在?

我有如下功能:

const char* get_message() {
    return "This is a constant message, will NOT change forever!";
};

const char* get_message2() {
    return "message2";
};
Run Code Online (Sandbox Code Playgroud)

我计划在我的应用程序的任何地方使用它们,即使在不同的线程中。

const char*我想知道这些字符串的生命周期,即在函数之外使用这些字符串是否安全get_message

我猜想硬编码const char*字符串将被编译到应用程序的代码段而不是数据段中,所以也许像上面那样使用它们是安全的?

c++ constants lifetime null-terminated constexpr

12
推荐指数
4
解决办法
1058
查看次数

如何在 CMake 中安装时重命名/修改目标文件的版本号?

我正在使用 CMake-3.13.4 和 KDevelop-5.2.1。

我有一个最顶层的 CMakeLists.txt,它定义了我的目标的版本号。看起来像:

set( PROJECT_VERSION_MAJOR 1 )
set( PROJECT_VERSION_MINOR 4 )
set( PROJECT_VERSION_PATCH 7 )
...
add_executable( mytarget main.cpp XXX.cpp ... )
target_link_libraries( mytarget "stdc++fs" ${CMAKE_THREAD_LIBS_INIT} ... )
install( TARGETS mytarget RUNTIME DESTINATION . )
Run Code Online (Sandbox Code Playgroud)

我希望 CMake 自动将版本字符串附加到目标的文件名中。所以我的代码如下:

install( TARGETS mytarget RUNTIME DESTINATION . RENAME "mytarget-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}" )
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

有没有办法用CMake来完成?我最终想要的文件名是“mytarget-1.4.7”。

installation version kdevelop cmake lib

5
推荐指数
1
解决办法
4250
查看次数

为什么只有函数指针而不是函数变量?

在C/C++中,我们可以声明/定义一个类型的函数指针,然后声明/定义这个类型的一些变量。但我认为这是模棱两可的。

例如:

typedef void ( *pFunc )();
// typedef void ( aFunc )();
void theFunc() {
   cout << "theFunc has been called successfully." << endl;
};

int main() {
   pFunc pf0 = theFunc;
   pFunc pf1 = &theFunc;

   pf0();
   ( *pf0 )();
   pf1();
   ( *pf1 )();
};
Run Code Online (Sandbox Code Playgroud)

理论上,只有pFunc pf1 = &theFunc;(*pf1)();是合法的,但以上都可以通过编译。

Pascal语法中,我们需要分别定义函数的vars或函数指针的vars,它们的含义是不同的,而且更加清晰(至少我是这么认为的)!

此外,我们不能声明/定义函数的变量而不是函数指针的变量!我尝试了以下并失败了。

typedef void ( aFunc )();
aFunc af0 = theFunc;
Run Code Online (Sandbox Code Playgroud)

如果使用其他类型,例如 int/double,则有非常严格的语法限制我们正确使用它们。(如果int*与 不同int,为什么*pf0与 相同pf0?!) …

c++ typedef function-pointers function

5
推荐指数
1
解决办法
191
查看次数

将 CPU 频率指定为 Linux 启动时的内核 CMD_LINE 参数?

我用 i7 CPU 替换了我笔记本电脑的 i5 CPU,以便它可以运行得更快。但是因为i7的功率更大,温度也比以前高,所以我的笔记本经常死机。所以,我用 cpupower 来指定 CPU 的 MAX 频率,它起作用了。现在,我的问题是“有没有办法在启动时将 CPU 频率指定为 linux 内核的 cmd_line 参数?”,这样我就可以确保系统稳定正确地启动。

顺便说一句,如果新的cpu最多在2.5GHz的频率下运行,一切都好,性能比旧的高一倍。所以我觉得换我的CPU是值得的。

多谢!

linux cpu kernel frequency

4
推荐指数
1
解决办法
3255
查看次数

std :: string的对象真的可以移动吗?

正如我们所知,当一个可移动的物体被分配给另一个相同类型的物体时,它将不会被深深地复制.通过这种方式,我们可以节省大量时间.但是今天,我发现了一种现象.请查看以下代码.

#include <string>
#include <iostream>
int main() {
std::string s1 = "s1";
std::string s2 = "s2";

std::cout << "  s1[" << ( void* ) &s1[0] << "]:" + s1
    << ", s2[" << ( void* ) &s2[0] << "]:" + s2
    << std::endl;
s1.swap( s2 );
std::cout << "  s1[" << ( void* ) &s1[0] << "]:" + s1
    << ", s2[" << ( void* ) &s2[0] << "]:" + s2
    << std::endl;

s2 = std::move(s1);
std::cout << "  s1[" …
Run Code Online (Sandbox Code Playgroud)

c++ string pointers move-semantics

3
推荐指数
1
解决办法
268
查看次数

为什么 std::errno 不存在而“errno”存在?

为了让我的代码更符合C++风格而不是C风格,我想替换errnostd::errno,并替换include <errno.h>include <cerrno>.

令我惊讶的是,这些都不是std::errno

众所周知,许多 C 事物都有 C++ 等价物。举例来说:

在 c-source.c 中,我们通常这样编码:

#include <string.h>
print( strerro(1) );
Run Code Online (Sandbox Code Playgroud)

在c++source.cpp中,我们可以这样做:

#include <cstring>
std::cout << std::strerro(1);
Run Code Online (Sandbox Code Playgroud)

为什么存在却不std::errno存在std::strerro

c++ namespaces std errno

3
推荐指数
1
解决办法
66
查看次数

strncpy/memcpy/memmove 是否逐字节或以其他有效方式复制数据?

众所周知,在 x86/x86_64 等多字节字计算机中,逐字复制/移动大量内存(每步 4 或 8 个字节)比逐字节复制/移动更有效。

我很好奇 strncpy/memcpy/memmove 会以哪种方式做事,以及它们如何处理内存字对齐。

char buf_A[8], buf_B[8];

// I often want to code as this
*(double*)buf_A = *(double*)buf_B;

//in stead of this
strcpy(buf_A, buf_B);
// but it worsen the readability of my codes.
Run Code Online (Sandbox Code Playgroud)

memcpy effective-c++ strcpy strncpy memmove

2
推荐指数
1
解决办法
2741
查看次数

如何在工厂方法之外禁用创建/复制 obj?

我有一个类,它的负载非常重,因此创建/复制/移动此类的实例非常昂贵。由于应用程序完成初始化后它们不会改变,因此无需创建此类的临时对象。我只需要在容器(std::map)中缓存对象,并在需要时提供“常量引用”。

必须强调的一点是,我正在寻找一种解决方案,可以在将对象添加到容器之前避免双重创建或不必要的复制(我不认为像 @getsoubl 提出的解决方案可以解决问题,因为它不会消除双重创建或不必要的复制)。

因此,我想将构造函数方法安排到类主体的“私有/受保护”部分,以禁止在“工厂方法”之外进行任何创建/复制/移动。以下是我的原始解决方案:

class MyClass {
public:
   // methods of the class
   static const MyClass & findObject( int iKey ) {
      auto pair = mapObjects.try_emplace( iKey, iKey );
      if ( pair.second )
         cout << "New object has been created" << endl;

      return pair.first->second;
   };

   // deleted
   MyClass() = delete;
   MyClass( MyClass & ) = delete;
   MyClass( MyClass && ) = delete;
   MyClass( const MyClass & ) = delete;
   MyClass( const MyClass && ) = delete;
   MyClass …
Run Code Online (Sandbox Code Playgroud)

c++ factory factory-pattern move-constructor emplace

2
推荐指数
1
解决办法
120
查看次数

如何从没有虚拟析构函数的类派生?

有一个虚拟类作为回调接口,我既不能修改,也不能要求作者修复。类的唯一成员是很多可以覆盖的虚方法,以便让库回调到我的代码中。为了获得一些回调机会,我应该为那个虚拟类创建一个派生类,并覆盖相应的虚拟方法。如果我对某些回调机会不感兴趣,我只需要避免覆盖它们。

但是,该接口类的声明有一个缺陷——它的析构函数没有声明为 virtual

例如:

class callback_t {
public:
  virtual void onData( int ) {};
};
Run Code Online (Sandbox Code Playgroud)

我创建了一个子类并且不覆盖析构函数,但是当我删除类的动态对象时child_t,我遇到来自编译器的警告(gcc9 with C++17):

删除具有非虚拟析构函数的多态类类型“child_t”的对象可能会导致未定义的行为。

class child_t : public callback_t {
public:
  ~child_t() {
    // release things specific to the child...
  };
  void onData( int ) override {
    // do things I want when onData
  };

private:
  int m_data = 0;
};

int main() {
  child_t* pc = new child_t;

  // pass pc into the routines of the library
  // …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism overriding derived-class virtual-destructor

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

在没有 gcc8 的生产环境中运行使用 gcc8 构建的程序

我的开发/生产环境都是 CentOS-7.7。为了用 gcc-8.3.0 编译我的程序,我在我的开发环境中安装了“devtoolset-8”,但它不能像 CentOS7 最初附带的 gcc-4.8.5 一样使用。每次需要编译程序时,必须使用“scl enable devtoolset-8 -- bash”切换到gcc8而不是gcc4.8.5。

当程序部署到生产环境时,没有gcc8,也没有libstdc++.so.6.0.25,所以它不能运行。我猜 libstdc++.so.6.0.25 应该和 gcc8 一起发布?我既不能在生产环境上安装“devtoolset-8”,也不能在生产环境上从源代码构建 gcc8。CentOS官方yum repo安装的libstdc++版本是libstdc++.so.6.0.19,所以我的程序无法在production-env中加载。如何让这样的程序运行?

谢谢!请原谅我丑陋的英语。

gcc centos yum libstdc++ devtoolset

0
推荐指数
1
解决办法
210
查看次数

如何指定初始化具有构造函数的 C++ 结构?

我有一个非常大的结构,它具有自定义的复制构造函数、自定义的移动构造函数、自定义的移动分配器和自定义的复制分配器,但我还需要在某处使用指定初始化语法来初始化它,因为它非常大,而我只想仅初始化其中的几个字段,其余字段保留默认值。

\n

例如:

\n
struct SA_t {\n    int a;\n    int b;\n    int c;\n};\n\nint main() {\n    SA_t sa1 { .a = 2, .b = 3, .c = 4,};  // no problem\n    return EXIT_SUCCESS;\n};\n
Run Code Online (Sandbox Code Playgroud)\n

但是当我为其添加自定义构造函数时,我根本无法使用指定初始化方法。

\n
struct SA_t {\n    SA_t() {\n        a = 0;\n        b = 1;\n        c = 2;\n    };\n\n    int a;\n    int b;\n    int c;\n};\n\nint main() {\n    SA_t sa1 { .a = 2, .b = 3, .c = 4,};  /* no matching function for call to …
Run Code Online (Sandbox Code Playgroud)

c++ constructor initialization default-constructor designated-initializer

0
推荐指数
1
解决办法
495
查看次数

如何完美转发一个常量引用或可移动右值的通用引用?

我用 C++20 编写了一个无锁且线程安全的环形队列,到目前为止它可以工作。唯一不完美的是它必须有两个enque()方法,一个接受对左值的 const 引用作为参数,另一个接受对右值的引用,以便将右值移入队列而不是再次构造。

\n

之前版本的代码如下,只是一个骨架,进行简化:

\n
template <typename T>\nclass RingQue_t {\npublic:\n    explicit RingQue_t( size_t capacity );\n    ~RingQue_t();\n    bool deque( T& dest_ ) { return true; };\n\n    // If we offer a const ref, the compiler will select this one\n    bool enque( const T& src_ ) {\n        // a lot of same codes goes here for a same logic...\n\n        new( _buff + _tail ) T( src_ );\n    };\n\n    // If we offer a rvalue ref, the compiler …
Run Code Online (Sandbox Code Playgroud)

c++ copy-constructor rvalue-reference move-constructor perfect-forwarding

-1
推荐指数
1
解决办法
160
查看次数