我是一个导致gcc崩溃的错误。实际上它可能是技术规范中的一个错误,或者只是我应该知道的东西。这就是我问这个问题的原因。
在编译时看起来我可以在需要表达式(示例中的ALTERNATIVE 1)中执行约束检查的意外递归行为。我可以通过结合概念分解 require表达式来解决问题(参见示例中的ALTERNATIVE 2)。我使用的事实是&&如果第一个测试是真的,则运算符不执行第二个测试。
以下是导致我的错误的代码示例:
#include <vector>
template <class T> bool concept ValueGettable = requires(T a) { {a.value()}; };
template <class T> struct owner {
T i;
const T &value() const & { return i; }
};
///////////
template <class T> decltype(auto) get_value(T &&a) {
return a;
}
template <ValueGettable T> decltype(auto) get_value(T &&a) {
return a.value();
}
//////////// ALTERNATIVE 1 => causes gcc infinite looping until segfault
template <class T, class U>
bool concept ValueEqualComparable = requires(T a, U b) {
requires ValueGettable<T> || ValueGettable<U>;
{ get_value(a) == get_value(b) }->bool;//if this line is removed the
//the code compiles and run fine.
};
//////////// ALTERNATIVE 2 => works fine
//template <class T, class U> bool concept OrValueGettable = requires(T a, U b) {
// requires ValueGettable<T> || ValueGettable<U>;
//};
//template <class T, class U> bool concept CompareEqualGot = requires(T a, U b) {
// { get_value(a) == get_value(b) }
// ->bool;
//};
//template <class T, class U>
//bool concept ValueEqualComparable =
// OrValueGettable<T, U> &&CompareEqualGot<T, U>;
///////////////// END ALTERNATIVES
ValueEqualComparable { T, U }
bool operator==(const T &a, const U &b) { return get_value(a) == get_value(b); }
int main() {
auto a = 0;
auto b = owner<int>{0};
a == b;
std::vector<int> v;
auto c = v.begin();
auto d = owner<std::vector<int>::iterator>{v.begin()};
c == d; //if this line is removed the code
//compiles and run without error.
return 0;
}
我知道需要表达式中的需求被评估为需求的cunjunction。因此,我认为问题在于,即使需求失败,后续需求也会导致实例化,而在联合情况下(ALTERNATIVE 2),此实例化不会执行。
就我而言,这可能是TS概念的一个错误:实现概念会更容易,好像连词是作为if constexpr
的连续实现的,或者可能已经是这种情况了? / p>
Nota:无论答案是什么,gcc 6.2都有漏洞,但我无法将错误发布到buggzilla:我无法创建帐户。