我被赋予了完善编解码器库接口的任务。我们使用的是C ++ 17,我只能使用标准库(即没有Boost)。当前,有一Decoder类大致如下所示的类:
class Decoder : public Codec {
public:
struct Result {
vector<uint8_t>::const_iterator new_buffer_begin;
optional<Metadata> metadata;
optional<Packet> packet;
};
Result decode(vector<uint8_t>::const_iterator buffer_begin,
vector<uint8_t>::const_iterator buffer_end);
private:
// irrelevant details
};
Run Code Online (Sandbox Code Playgroud)
调用者实例化一个Decoder,然后通过以下方式将数据流馈送到解码器:
从文件中读取大量数据(但将来可能还会有其他来源),并将其附加到vector<uint8_t>。
调用该decode函数,并为其向量传递迭代器。
如果返回Result的new_buffer_begin与buffer_begin传递给的相同,则decode意味着缓冲区中没有足够的数据来解码任何内容,并且调用方应返回到步骤1。否则,调用方将使用已解码的Metadata或Packet对象。 ,然后返回到步骤2,new_buffer_begin用于下一遍。
我对这个介面不满意,需要改善的地方:
使用vector<uint8_t>::const_iterator似乎过于具体。有没有更通用的方法不强制调用者使用vector?我当时正在考虑仅使用C风格的界面;一个uint8_t *和一个长度。有没有相当通用的C ++替代品?
如果有足够的数据来解码某些内容,则只有metadata 或 packet将有一个值。我认为std::variant2个回调(每种类型一个)将使此代码更具自说明性。我不确定哪个更惯用。每种方法的优缺点是什么,是否有更好的方法?
我正在使用vectorc ++程序(我是初学者).
我需要发送一部分vector功能.
如果是c我需要这样做(使用数组):
int arr[5] = {1, 2, 3, 4, 5};
func(arr+2); //to send part array {3, 4, 5}
Run Code Online (Sandbox Code Playgroud)
除了vector用最后一部分创建一个新的方法之外还有其他方法吗?
我知道这可能与问题重叠:什么是 \xe2\x80\x9cspan\xe2\x80\x9d 以及我何时应该使用它?,但我认为问题的这个特定部分的答案相当令人困惑。一方面,有这样的引用:
\n\n\n如果您有一个标准库容器(或 Boost 容器等),并且您知道它最适合您的代码,请不要使用它。它无意取代其中任何一个。
\n
但在同一个答案中,出现了这样的说法:
\n\n\n当您希望数据在内存中连续时,是将 const vector& 传递给函数的合理替代方案。再也不用被 C++ 大师骂了!
\n
那么我没有到达哪一部分呢?我什么时候会这样做:
\nvoid foo(const std::vector<int>& vec) {}\nRun Code Online (Sandbox Code Playgroud)\n而这是什么时候呢?
\nvoid foo(std::span<int> sp) {}\nRun Code Online (Sandbox Code Playgroud)\n还有,这会不会
\nvoid foo(const std::span<int> sp) {}\nRun Code Online (Sandbox Code Playgroud)\n有什么意义吗?我认为不应该,因为 astd::span只是 a struct,包含指针和长度。但是,如果它不能阻止您更改std::vector作为参数传递的值,那么它如何替换const std::vector<T>&?
是否有可能从一个向量中获取一个const迭代器,该向量只能在无效之前迭代某个向量范围?
例如,如果我有一个10个元素的向量,我想返回元素4到7的迭代器.
伪代码:
int main()
{
std::vector<int> vector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
auto iterator = GetRangedIterator(vector, 4, 7)
for (const int& num : iterator)
print num; // 4, 5, 6, 7
}
Run Code Online (Sandbox Code Playgroud) 所以我有这个功能......
virtual void CallRemoteFunction( const char* pServerGameObjectId, const char* pFunctionName, OVariant arg1 = OVariant(), OVariant arg2 = OVariant(), OVariant arg3 = OVariant(), OVariant arg4 = OVariant(), OVariant arg5 = OVariant(), OVariant arg6 = OVariant(), OVariant arg7 = OVariant(), OVariant arg8 = OVariant(), OVariant arg9 = OVariant() );
Run Code Online (Sandbox Code Playgroud)
我决定重写这个功能,因为坦白说,我很尴尬.该函数很简单......采用可变数量的未知类型的参数并执行操作.
我对现代C++很新,所以我做了一些搜索,并假设我会找到一些简单/优雅的新方法.我想象了......
//hypothetical code
virtual void CallRemoteFunction( const char* pServerGameObjectId, const char* pFunctionName, ... args )
{
std::vector<OVariant> argsArray;
for (auto& arg : args )
{
argsArray.push_back(arg)
}
//do other stuff
}
//end …Run Code Online (Sandbox Code Playgroud) 在过去一年左右的时间里,我注意到 StackOverflow 上有一些与 C++ 相关的答案mdspan,但我从未在 C++ 代码中真正看到过这些答案。我尝试在 C++ 编译器的标准库目录和C++ 编码指南中查找它们- 但找不到它们。我确实找到了std::span;我猜它们是相关的——但是如何呢?添加“md”代表什么?
请解释一下这个神秘实体的用途,以及我何时需要使用它。
我想在我的类中隐藏一个向量字段,但允许通过其元素轻松迭代,但没有别的.这样班级的客户就可以做到
for (auto element : foo.getElements()) { }
Run Code Online (Sandbox Code Playgroud)
但不是
foo.getElements()[42];
Run Code Online (Sandbox Code Playgroud)
是否有一些简单的方法来实现这一点而不会产生新的混淆类型?
你如何以正式和严格的方式定义(解释)什么是 C++ 中的引用类型?
我试着用谷歌搜索,并查看了 Stroustrup 的“C++ 编程语言”,但我在那里没有看到这个概念的定义。
我有以下代码:
template <typename T, ::std::size_t size>
using ary_t = T[size];
template <typename T, ::std::size_t size>
constexpr int call_me(ary_t<T const, size> &a)
{
int total = 10;
for (::std::size_t i = 0; i < size; ++i) {
total += a[i];
}
return total;
}
template <typename T>
constexpr int call_me(T const *a)
{
int total = 0;
for (int i = 0; a[i]; ++i) {
total += a[i];
}
return total;
}
#if 0
int t1()
{
return call_me("a test");
} …Run Code Online (Sandbox Code Playgroud) 我想编写一个带有一个参数的C++函数,以便可以传入以下任何一种类型:
std::vector<int>
std::array<int>
int array[numElements]
int *ptr = new int[numElements]
etc
Run Code Online (Sandbox Code Playgroud)
模板是实现这一目标的最佳方式吗?