【问题标题】:Problem with requires clause inside if constexprif constexpr 内部的 requires 子句有问题
【发布时间】:2020-02-23 12:49:05
【问题描述】:

在尝试基于if constexpr and requires-expression for ad-hoc concepts checking 实现if constexprrequires clause 时遇到以下问题:

template<class P>
concept TuplePair = requires(P p) {
    requires std::tuple_size<P>::value == 2;
    std::get<0>(p);
    std::get<1>(p);
};

void print(const auto& p) {
    if constexpr( TuplePair<decltype(p)> ) {
        std::cout << std::get<0>(p) << ", " << std::get<1>(p) << std::endl;
    }
    else {
        std::cout << "else" << std::endl;
    }
}

int main() {
    // justifiably prints 'else':
    print(std::make_tuple(3, 4, 5));

    // prints 'else' even though this is a valid TuplePair:
    print(std::make_tuple(1, 2));
}

if constexpr requires clause 有什么问题?

【问题讨论】:

  • 显然问题是你没有将这个概念命名为Twople
  • 谢谢@Casey,很荣幸有concepts 帮我解答我的愚蠢问题。 Twople 应该清楚地告知编译器该事物的含义并避免其余代码:-)

标签: c++ c++20 c++-concepts if-constexpr


【解决方案1】:

p 是一个引用,因此decltype(p) 是一个引用类型。对于引用类型std::tuple_size 将无法正常工作。所以概念检查没有通过。您可以使用std::remove_cvref_t 来获取普通的引用类型

TuplePair<std::remove_cvref_t<decltype(p)>>

Live Demo

【讨论】:

  • 谢谢,基本的 :-) 有没有办法缩短表达式,使 TuplePair(或其他其他概念)表现为 bool,所以表达式可以很简单: if constexpr( TuplePair> )?
  • @AmirKirsh - 我不确定我是否理解。你的建议应该已经有效godbolt.org/z/LPsNbh
  • @AmirKirsh 或者,您可以使用两个重载:void print(const TuplePair auto&amp; p) void print(const auto&amp; p) 来处理这两种情况,具体取决于用例。
  • 为什么不直接使用带有const T&amp; 的(传统)模板参数,这样T 就不会包含引用?
猜你喜欢
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多