标签: c++98

如何用 C++ 编写自定义流转换?

在大量使用 Haskell 和函数式语言之后,我开始学习 C++,我发现我一直在尝试解决同样的问题:

  • 从输入流中读取一些数据
  • 根据特定算法对它们进行标记
  • 处理令牌

如果这是 Haskell,我可以简单地利用一切都是懒惰的事实,并在我想到的时候编写我的转换,然后它会在下游被消耗时应用。甚至有一些库可以执行这种精确的模式(导管管道)。

假设我想获取序列1 2 3 4 5 6 ...和输出12 34 56 ...。我可以了解如何编写在流上运行并就地处理数据的临时代码。但我想知道是否存在一种抽象机制,允许我通过转换来自另一个流的数据(以任何可以想到的方式)来构建新的流。这种抽象应该允许我在处理数据时缓冲数据,而不仅仅是单个元素到新值的简单映射。

以下是限制:

  • 除了 stdlib 之外,我无法使用任何其他库。
  • 它必须适用于 C++03(意味着没有 C++11 功能。)

如果你在想,这是作业吗?好吧,我收到了很多类作业,这些作业要求我处理数据流(这就是没有库和 C++03 限制的原因)。并不是我不知道如何使用while循环来做到这一点,而是我想知道 stl 中是否存在现有的流抽象,只是等待被发现和使用。

但如果唯一的方法是使用 C++11,那么我想知道。

c++ stream stream-processing c++03 c++98

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

CreateProcessW 不尊重命令行

我正在尝试在 dll 中实现 CreateProcessW,以便用户可以在单独的进程中启动应用程序。

对于初学者,我正在对代码中的命令进行硬编码,直到我弄清楚为止。

我有

STARTUPINFO si = {sizeof(STARTUPINFO), 0};
si.cb = sizeof(si);
PROCESS_INFORMATION pi = {0};
LPCTSTR AppName=L"c:\\utilities\\depends.exe";
LPTSTR Command = L"c:\\utilities\\tee.exe";
if (CreateProcessW(AppName, Command, 0, 0, 0, CREATE_DEFAULT_ERROR_MODE, 0, 0, &si, &pi)) {
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return GX_RESULT_OK;
    } else {
        .. show error msg
    }
Run Code Online (Sandbox Code Playgroud)

这将启动 Depends,但不会打开 Tee.exe。没有错误,它只是忽略命令行参数。参数是正确的,我可以在运行提示下运行它,它工作正常。如果我将 AppName 留空并指定 Depends.exe 作为命令参数它也可以工作,但如果我指定

LPTSTR Command = L"c:\\utilities\\depends.exe c:\\utilities\\tee.exe";
Run Code Online (Sandbox Code Playgroud)

我收到错误 3:“系统找不到指定的路径”。

此外,通过指定 lpCurrentDirectory 参数,它同样会被忽略。

c++ winapi c++builder c++98

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

具有多重继承的 C++ 协变返回类型错误

我有与此等效的代码:

class X {};
class Y {};

template< typename T>
  class C {
  public:
      virtual  T * foo() = 0;
  };

class A : public C< X> {
public:
    X * foo() {};
};

class B : public A {};

class D : public B, public C< Y> {
public:
    Y * foo() {}; //this is the only one method I need here. Not A::foo!
};
Run Code Online (Sandbox Code Playgroud)

我收到这个错误:

error:   invalid covariant return type for 'virtual Y* D::foo()'
 Y * foo() {}; …
Run Code Online (Sandbox Code Playgroud)

c++ multiple-inheritance covariant c++98

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

在 C++98 中实现移动构造函数和移动赋值运算符以获得更好的性能

我可以在 C++98 中使用复制构造函数和赋值运算符模拟移动构造函数和移动赋值运算符的功能,以提高性能,只要我知道复制构造函数和复制赋值将只为代码中的临时对象调用,或者我在我的代码中插入针吗?眼睛?

我举了两个例子,一个是普通的复制构造函数和复制赋值运算符,另一个是模拟移动构造函数和移动赋值运算符,并在向量中推送 10000 个元素来调用复制构造函数。

普通复制构造函数和复制赋值运算符的示例(copy.cpp)

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

class MemoryBlock
{
public:

   // Simple constructor that initializes the resource.
   explicit MemoryBlock(int length)
      : _length(length)
      , _data(new int[length])
   {
   }

   // Destructor.
   ~MemoryBlock()
   {

      if (_data != NULL)
      {
         // Delete the resource.
         delete[] _data;
      }
   }


//copy constructor.
MemoryBlock(const MemoryBlock& other): _length(other._length)
      , _data(new int[other._length])
{

      std::copy(other._data, other._data + _length, _data);
}

// copy assignment operator.
MemoryBlock& operator=(MemoryBlock& other)
{
  //implementation of …
Run Code Online (Sandbox Code Playgroud)

c++ constructor vector copy-constructor c++98

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

C++98 正确检查空指针

C++11引入了nullptr我没有的关键字。

我想有NULL来自 C的宏,我从这里这里的一些东西中读到了在 C++ 中使用的宏,但我仍然不确定在这个旧的 C++ 标准中检查空指针的正确方法是什么。

我基本上希望能够使用 Boost Test 为我的测试用例编写此代码:

aWrapperDataStructure x;
BOOST_CHECK_NE(x.get_ptr(), static_cast<decltype(x.get_ptr())>(nullptr));
Run Code Online (Sandbox Code Playgroud)

但也许,正如 Tutorials Point 建议的那样,考虑到限制,这样的事情更合适:

BOOST_CHECK(x.get_ptr()); //true when not NULL
Run Code Online (Sandbox Code Playgroud)

不过,关于这方面的一些事情让我感到厌烦,所以我想知道这里的最佳做法是什么。如果它在网上的某个地方,或者在 SO 上,它已经被埋藏很久了,我找不到它。谢谢!

null-pointer c++98

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

如何在旧 C++ 中初始化 const std 向量?

我的 C++ 编译器标识是 GNU 4.4.1

我认为从 c++ 11 开始,您可以通过以下方式初始化向量:

const std::vector<int> myVector = {1, 2, 3};
const std::vector<int> myVector2{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

不幸的是,我没有使用 c++ 11,所以 myVector 只能由构造函数初始化。我需要创建一个永远不会被修改的向量。它必须由类中的不同函数共享,因此它也可以是静态的,甚至是类成员。有没有办法让我的向量在 c++98 中定义时被初始化,如上面的例子,或者等价的东西?

c++ constants stdvector c++98

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

(a=1)=2 在 C++98 中是未定义的行为吗?

类似的代码例如(a+=1)%=7;,其中 a 是一个int变量。

我们知道运算符+=or=不是序列点,因此我们在两个相邻的序列点之间有两个副作用。(我们这里使用的是cpp98的序列点规则)

然而,赋值运算符喜欢+==保证在赋值后返回左值,这意味着执行顺序在某种程度上是“定义的”。

那么这是一种未定义的行为吗?

c++ undefined-behavior sequence-points language-lawyer c++98

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

C++抽象工厂应该为构造对象提供破坏方法吗?

考虑以下接口(使用哑指针,因为我们仍然在C++ 98中)

class WidgetMaker {
    virtual Widget* makeWidget() = 0;
};
Run Code Online (Sandbox Code Playgroud)

具有以下可能的实现

class SpecificWidgetMaker: public WidgetMaker {
    Widget* makeWidget() {
        return new SpecificWidget();
    }
};
Run Code Online (Sandbox Code Playgroud)

Widget是一些带有虚析构函数的基类,SpecificWidget扩展了它.我的同事们声称WidgetMaker界面应该包含以下方法

virtual void freeWidget(Widget* widget);
Run Code Online (Sandbox Code Playgroud)

理由是这样我们不会强制makeWidget实现使用标准的新分配,它们可以使用自定义池分配器,或者总是返回相同的全局实例,以防小部件无状态或其他.

我觉得这样的设计通常是一个坏主意 - 它使客户端代码变得复杂,违反了KISS和YAGNI,在未来20年内将转换(在我们的组织中不太可能)转换为unique_ptr更难.我应该相信自己的感受吗?当自由方法作为抽象工厂接口的一部分被证明是合理的时候是什么情况?

c++ oop c++98 creation-pattern

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

从默认参数中推断模板参数

考虑以下代码:

#include <functional>

template <typename T,typename COMP>
bool foo(T a,T b,COMP c = std::less<T>()) { 
    return c(a,b); 
}

bool bar(int a, int b){ return a<b;}

int main(){
    foo(1,2,bar);               // OK
    foo(1,2,std::less<int>());  // OK
    foo(1,2);                   // error
}
Run Code Online (Sandbox Code Playgroud)

前两个调用很好,但似乎禁止让编译器COMP从默认参数中推断出类型:

<source>:14:5: error: no matching function for call to 'foo'    
    foo(1,2);    
    ^~~    
<source>:4:6: note: candidate template ignored: couldn't infer template argument 'COMP'    
bool foo(T a,T b,COMP c = std::less<T>()) {    
     ^   
1 error generated.    
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?我真的不明白为什么编译器"无法推断模板参数'COMP'",我宁愿怀疑它不允许这样做.

是否可以从默认参数推断出模板参数?如果没有,为什么?

c++ templates default-parameters c++98

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

可以根据c ++中的模板args更改类成员吗

我希望可以根据模板参数更改类成员。我想要类似的东西

template<int value>
class MyClass
{
public:
   void print()
   {
      // using the member
      std::cout << sizeData() << std::endl;
      for (int i=0;i<sizeData();i++)
      {
         std:cout << data[i] << std::endl;
      }
   }
   static int sizeData()
   {
     #if value == 1
        return 3;
     #endif
     #if value == 2
        return 6;
     #endif
   }
   static int sizeArray()
   {
     #if value == 1
        return 40;
     #endif
     #if value == 2
        return 200;
     #endif
   }
private:
   #if value == 1
      int data[3];
      const static int array[40];
   #endif …
Run Code Online (Sandbox Code Playgroud)

c++ c++98

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