Проблема с удовлетворением концепции C++ в std::visitC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Проблема с удовлетворением концепции C++ в std::visit

Сообщение Anonymous »

У меня есть концепция C++, в которой мне нужно проверить, имеет ли класс определенный общедоступный атрибут.
Моя проблема в том, что эта концепция работает, если я использую ее напрямую, но не работает, если я использую ее в std::visit.
Это рабочий пример:

Код: Выделить всё

#include 
#include 

template 
concept ControllerConcept = [] {
return requires (T controller) {
{ controller.tick(0.0) } -> std::convertible_to;
{ T::Name } -> std::convertible_to;
};
}();

class TestClass {
public:

inline constexpr static char Name[]{"TheName"};

public:

double tick(double t) {
return t * 0.5;
}
};

int main(int argc, char* argv[]) {
TestClass value{};
static_assert(ControllerConcept, "Controller does not satisfy ControllerConcept.");
return 0;
}
Это работает в MSVC, Clang и GCC: если я прокомментирую строку Name в TestClass, компиляторы выдадут ошибку.
Теперь все становится немного сложнее. Я хочу создать в своем коде множество классов и поместить их в std::variant. Я также хочу проверить, что классы соответствуют ControllerConcept, поэтому я помещаю статическое утверждение внутрь посетителя (где я использую технику VariantOverload. Это мой новый код:

Код: Выделить всё

#include 
#include 
#include 

// Definition of the variant overload utility
template
struct VariantOverload : Ts ... {
using Ts::operator() ...;
};
template VariantOverload(Ts...) -> VariantOverload;

// This is the usual concept
template 
concept ControllerConcept = [] {
return requires (T controller) {
{ controller.tick(0.0) } -> std::convertible_to;
{ T::Name } -> std::convertible_to;
};
}();

// The class inside the variant
class TestClass {
public:

inline constexpr static char Name[]{"TheName"};

public:

double tick(double t) {
return t * 0.5;
}
};

// The variant
using Value = std::variant<
TestClass
>;

int main(int argc, char* argv[]) {
Value value = TestClass{};

// I'm visiting the visitor in order to call the method, and inside it I check if the class
// satisfies the concept
VariantOverload visitor{
[](auto& controller) -> double {
static_assert(ControllerConcept, "Controller does not satisfy ControllerConcept.");
return controller.tick(2.0);
}
};
return std::visit(visitor, value);
}
Теперь компиляция завершается с ошибкой в MSVC, Clang и GCC, и все ошибки говорят о том, что концепция не удовлетворена (насколько я понимаю).
Я думал об ошибке в моем коде, но странно то, что если я прокомментирую { T::Name } -> std::convertible_to; в концепции, я смогу успешно скомпилировать код даже во втором случае, так что я думаю что код проверки концепции правильный.
Поэтому я не понимаю, что происходит. Если концепция работает с первым фрагментом кода, почему она больше не работает во втором?
А если я правильно проверю концепцию внутри посетителя, почему проверка T::Name работает в первом случае, а не во втором?
Я думаю, что это моя ошибка, а не компилятора, во-первых, потому что я недостаточно умен, чтобы выдавать ошибки компиляторам, а также потому, что у меня проблема со всеми тремя компиляторы.
Можете ли вы мне помочь? Как правильно использовать это понятие во втором случае?

Подробнее здесь: https://stackoverflow.com/questions/798 ... a-stdvisit
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»