我可以有一个同时接受 const-ref 和非 const-ref 指针的 C++ 方法吗?

问题描述 投票:0回答:1

我有一些辅助方法,它们通过引用接受指针,如果满足某些条件,则将其向前推进。这是一个例子:

char32_t readCodePoint(const char8_t *&current, const char8_t *end) {
  assert((current < end) && u8"At least one byte of input must be available");

  char8_t leadCharacter = *current;
  if(leadCharacter < 128) {
    ++current;
    return static_cast<char32_t>(leadCharacter);
  } else if((leadCharacter & 0xE0) == 0xC0) {
    // ...code for 2, 3 and 4 byte code points omitted...
    // (all increment 'current' accordingly and respect 'end')
  }

  // Sequence invalid or truncated
  return char32_t(-1);
}

现在我可以在

const char8_t *
指针上使用该方法,但它会强制指针变为
const
。以下将导致编译错误:

void collapseDuplicateWhitespace(std::u8string &utf8String) {
  char8_t *current = utf8String.data();
  char8_t *end = current + utf8String.end();

  while(current < end) {
    // ERROR: 'current' is a 'char8_t *' not a 'const char8_t *'
    char32_t codePoint = readCodePoint(current, end);
    // ... other logic ommitted ...
  }

  // ... resize string to new, shorter length ...
}

显然,

const_cast
的结果也不能直接作为引用传递,因此它会在调用方产生一些非常难看的代码,甚至可能在发布版本中引入别名问题。

是否有一种优雅的(最好是可读的)方式可以更改此方法以将

const char8_t *&
char8_t *&
作为
current
的类型?

c++ string pointers reference constants
1个回答
0
投票

唾手可得的解决方案是一个模板:

template <typename T, typename U>
concept possibly_const = std::same_as<T, const U> || std::same_as<T, U>;  

char32_t readCodePoint(possibly_const<char8_t> auto *&current, const char8_t *end) {
    // ...
}

另一个解决方案是重写代码以使用索引而不是指针,这消除了这里的常量问题:

char32_t readCodePoint(std::span<const char8_t> data, std::ptrdiff_t &index) {
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.