Как использовать `static_assert (std :: forward_iterator >);`C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как использовать `static_assert (std :: forward_iterator >);`

Сообщение Anonymous »

Я нашел немного (для меня) необъяснимого поведения в VS2022 и C ++ 20 со static_assert (std :: forward_iterator ) , кажется мне сломанным, или я не использую его в правильной фэйзии. Но поиск в Интернете я не могу найти никаких ссылок или размышлений о таких проблемах для него, также не здесь. Все используют стандарт C ++ 20 в VS2022.template
class my_container
...

template
class my_iterator
...

Итератор настроен как итератор , и я хочу протестировать с
static_assert(std::forward_iterator);

, который не удается.static_assert(std::input_iterator);
< /code>
Результаты сборки следующие: < /p>
Build started at 16:36...
1>------ Build started: Project: TestForwardIteratorConsole, Configuration: Debug x64 ------
1>TestForwardIteratorConsole.cpp
1> ...\TestForwardIteratorConsole\TestForwardIteratorConsole.cpp(7,20): error C2607: static assertion failed
1> ...\TestForwardIteratorConsole\TestForwardIteratorConsole.cpp(7,20):
1> the concept 'std::input_iterator' evaluated to false
1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(984,59):
1> the concept 'std::indirectly_readable' evaluated to false
1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(898,31):
1> the concept 'std::_Indirectly_readable_impl' evaluated to false
1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(891,21):
1> the concept 'std::same_as' evaluated to false
1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(891,21):
1> 'const int &' and 'int &' are different types
1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(891,11):
1> the expression was resolved to a call to 'my_iterator::operator *'
1> ...\TestForwardIteratorConsole\MyIterator.h(174,21):
1> see declaration of 'my_iterator::operator *'
1>Done building project "TestForwardIteratorConsole.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 16:36 and took 06,751 seconds ==========

(для меня необъяснимо) заключается в том, что тест для ввода итератор в порядке, когда эталонный оператор*() удален из шаблона.
, но это требование для прямого итератор.
обратно в книгу. Существует источник GITUB для всех примеров кода.
Одним из примеров является создание кольцо с итератором. Сломан. < /p>
Кто может дать мне предложение о том, как это исправить? Фактический контейнер и итерация предназначены только для проверки поведения и не имеют дальнейшего использования. Это не очень красивый код, но он служит целью показать проблему. Определение эталонного оператора*() находится в строке 180 и находится в комментарии.
// MyIterator templates and declarations
#pragma once

#include
#include
#include

template
class my_iterator;

template
class my_container
{
public:
using self_type = my_container;

using value_type = Value;
using reference = Value&;
using const_reference = const Value&;

using iterator = my_iterator;
using const_iterator = my_iterator;

friend my_iterator;

private:
std::map map;

public:
constexpr my_container() noexcept {}

my_container(const self_type& other) noexcept : map{ std::map(other.map) } {}

my_container(self_type&& other) noexcept : map{ std::map(other.map) } {}

virtual ~my_container() {}

self_type& operator=(self_type& other)
{
map = std::map(other.map);
return *this;
}

self_type& operator=(self_type&& other)
{
map = std::map(other.map);
return *this;
}

std::weak_ordering operator(self_type const& other) const noexcept
{
return map other.map;
}

bool operator==(self_type const& other) const noexcept
{
auto r = (*this other);
return (r == std::weak_ordering::equivalent);
}

bool operator!=(self_type const& other) const noexcept
{
auto r = (*this other);
return (r != std::weak_ordering::equivalent);
}

reference operator[](const Key key) noexcept
{
if (!map.contains(key)) map[key] = Value();
return map[key];
}

reference operator[](Key&& key) noexcept
{
if (!map.contains(key)) map[key] = Value();
return map[key];
}

reference at(const Key key) noexcept(false)
{
if (!map.contains(key)) throw std::out_of_range("key unavailable");
return map[key];
}

const_reference at(const Key& key) const noexcept(false)
{
if (!map.contains(key)) throw std::out_of_range("key unavailable");
return map[key];
}

void add(const Key key, Value& value) noexcept { map[key] = value; }
void add(const Key key, Value&& value) noexcept { map[key] = value; }

iterator begin() { return my_iterator(*this, 0); }
iterator end() { return iterator(*this, map.size()); }
};

template
class my_iterator
{
public:
using iterator_category = std::forward_iterator_tag;
using self_type = my_iterator;
using container_type = my_container;

using value_type = Value;
using reference = value_type&;
using const_reference = value_type const&;

using size_type = std::size_t;
using difference_type = std::ptrdiff_t;

private:
std::reference_wrapper container;
size_type index;

public:
explicit my_iterator(
container_type& container,
size_type const index) noexcept :
container(container),
index(index)
{ }

my_iterator(const self_type& other) noexcept :
container(other.container),
index(other.index)
{}

self_type& operator=(const self_type& other) noexcept
{
container = std::reference_wrapper(other.container);
index = other.index;
return *this;
}

bool comparable(self_type const& other) const noexcept
{
return (order(other) == std::weak_ordering::equivalent);
}

std::weak_ordering operator(self_type const& other) const noexcept(false)
{
if (!comparable(other)) throw std::logic_error("not comparable");
return index other.index;
}

bool operator==(self_type const& other) const noexcept(false)
{
return (*this other) == std::weak_ordering::equivalent;
}

bool operator!=(self_type const& other) const noexcept(false)
{
return (*this other) != std::weak_ordering::equivalent;
}

self_type& operator++() noexcept(false)
{
if (pass_end()) throw std::out_of_range("out of range");
inc();
return *this;
}

self_type operator++(int) noexcept(false)
{
if (pass_end()) throw std::out_of_range("out of range");
auto r = *this;
inc();
return r;
}

const_reference operator*() const noexcept(false)
{
if (pass_end()) throw std::out_of_range("out of range");
return lookupval(index);
}

//reference operator*() noexcept(false)
//{
// if (pass_end()) throw std::out_of_range("out of range");
// return lookupval(index);
//}

const_reference operator->() const noexcept(false)
{
if (pass_end()) throw std::out_of_range("out of range");
return lookupval(index);
}

reference operator->() noexcept(false)
{
if (pass_end()) throw std::out_of_range("out of range");
return lookupval(index);
}

private:
bool pass_end() const { return ( container.get().map.size()
Изменить после комментариев от @holyblackcat < /p>
Это какой -то код для тестирования, безопасно, предыдущий код в «myInterator.h» (и я извиняюсь за его размер, но я не видел, как сделать его более коротким, не сломавшись). < /p>
#include
#include "MyIterator.h"

static_assert(std::input_iterator);
//static_assert(std::forward_iterator);

int main()
{
std::cout

Подробнее здесь: https://stackoverflow.com/questions/797 ... y-iterator
Ответить

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

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

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

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

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