C++ if constexpr中requires子句存在问题

C++ if constexpr中requires子句存在问题,c++,c++20,c++-concepts,if-constexpr,C++,C++20,C++ Concepts,If Constexpr,在尝试使用requires子句实现if constexpr时,由于面临以下问题: 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 con

在尝试使用
requires子句实现
if constexpr
时,由于面临以下问题:

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));
}
模板
概念图TuplePair=需要(P){
需要std::tuple_size

::value==2; std::get(p); std::get(p); }; 无效打印(常数自动和p){ if constexpr(TuplePair){


std::cout
p
是一个引用,因此
decltype(p)
是一个引用类型。对于引用类型
std::tuple\u size
将无法正常工作。因此概念检查无法通过。您可以使用
std::remove\u cvref\u t
来获得普通引用类型

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

谢谢,初等:-)有没有办法缩短表达式,使TuplePair(或其他附加概念)表现为bool,这样表达式就可以很简单:if constexpr(TuplePair)?@AmirKirsh-我不确定我是否理解。你的建议应该已经在@AmirKirsh起作用了。或者,你可以使用两个重载:
void print(const TuplePair auto&p)
void print(const auto&p)
处理这两种情况,具体取决于使用情况。为什么不使用(传统的)使用
const T&
模板参数,以便
T
不包含引用?这个问题再次提出了一个问题,很明显,问题是您没有将这个概念命名为
Twople
。谢谢@Casey让
概念
帮我解决愚蠢的问题是一种荣幸。
Twople
应该清除y向编译器建议事情的含义,并排除代码的其余部分:-)