当前位置: 首页 > 知识库问答 >
问题:

除了在C 20中引入的显式(expr),还有C 14替代方案吗?

司知
2023-03-14

TL;DR:我正在寻找一个相当于以下C20MWe的C14:

template<int sz>
struct bits {
  int v; // note explicit(expr) below
  explicit(sz > 1) operator bool() const { return bool(v); }
};

int main() {
  bool c = bits<1>{1}; // Should work
  bool d = bits<3>{1}; // Should fail
}

背景:

我们有一个C类

然而,1位位向量(在我们的上下文中)几乎完全等同于布尔值,因此当sz==1时,运算符bool()应该是隐式的。

这可以通过显式(sz)来实现

我试图为sz==1重载运算符,但似乎显式的限定符也适用于它:以下操作不起作用。

template<int sz>
struct bits {
  int v;
  explicit operator bool() const { return bool(v); }
};

template<> bits<1>::operator bool() const {
  return bool(v);
}

int main() {
  bool c = bits<1>{1}; // Fails: "No viable conversion"
}

因此,问题是:我如何在C 14中指定运算符bool()应该只对sz显式

下面我为好奇的读者介绍一些背景知识。

背景:

这个问题出现在C语言中的嵌入式领域特定语言的上下文中。业务需求之一是操作符==返回一个

为了让好奇的读者更具体,以下程序在GNU上编译得很好,但在macOS上编译得不好,这是因为operator==onstd::array的实现方式:

#include <array>

struct S { explicit operator bool() const { return true; } };

struct T {};
S operator==(T, T) { return S(); }

int main() {
  std::array<T, 1> arr = { T() };
  return arr == arr;
}

这是因为在GNU libstdc的数组上实现=的过程中,有一个测试如果(!(*it1==*it2)),它会在s上调用显式运算符bool(),不会出现问题,在macOS上,库使用if(!_pred(*it1,*it2))_pred大致相当于bool__pred(sa,sb){return a==b;} ,不进行打字检查。


共有1个答案

颛孙镜
2023-03-14

是的。您可以使用SFINAE转换运算符:

#include <type_traits>

template<int sz>
struct bits {
  int v;
  explicit operator bool() const { return bool(v); }

  template <int S = sz>
  operator std::enable_if_t<S == 1, bool> () const { return bool(v);}
};

在螺栓上检查一下

int main()
{
  bool c1 = bits<1>{1};                    // Ok
  bool c2 = bits<3>{1};                    // error cannot convert
  bool c3 = static_cast<bool>(bits<3>{1}); // OK
}
 类似资料:
  • 编辑 认真地看一下切换你的电话和东西来改造。挺漂亮的。我很高兴我做了。有几个障碍,但很酷。

  • 需求是再页面内打开一个弹窗然后显示外部页面。 但是外部页面都是http 无法使用

  • 我想用逗号作为分隔符串联一个ArrayList。我找到了这个答案,说明在Java中使用是可能的。 无法解析方法“join(java.lang.String,java.lang.String,java.lang.String,java.lang.String, Android Studio是否有一个好的、简洁的替代方案(而不是使用for循环)?

  • 这可以用来强制假设所收集的元素是不同的 但是,在我看来,java doc已经过时了。不能用了。问题是JDK是否为java开发人员提供了对类似功能的访问(类似的方法、常量等),还是应该由开发人员自己编写?

  • 在这里学习我在Raku(neéPerl 6)的方法,非常好。但是我非常想念这个神奇的

  • 我需要在控制台上打印大量的数据(大约100兆)。在IntelliJ上使用println是很失败的。有没有像console.log这样的替代方案,可以处理和显示这些数据而不会出现滞后和减慢? 提前道谢!