Почему C ++ 20 не поддерживает «void f (Concept const auto &)»? - PullRequest
5 голосов
/ 09 апреля 2020
#include <string>

template<typename T>
concept HasSize = requires(T obj)
{
    obj.size();    
};

void f1(HasSize auto arg) {} // ok
void f2(HasSize auto&& arg) {} // ok
void f3(HasSize decltype(auto) arg) {} // ok
void f4(HasSize auto& arg) {}  // ok
void f5(HasSize auto* arg) {}  // ok

void f6(HasSize const auto& arg) {} // error

int main()
{
    std::string str{};

    f1(std::string{});
    f2(std::string{});
    f3(std::string{});
    f4(str);
    f5(&str);
    f6(str);
}

Скомпилировано с clang++ -std=c++20 -stdlib=libc++ z.cpp и сообщения об ошибках:

z.cpp:15:6: error: variable has incomplete type 'void'
void f6(HasSize const auto& arg) {} // error
     ^
z.cpp:15:9: error: too few template arguments for concept 'HasSize'
void f6(HasSize const auto& arg) {} // error
        ^
z.cpp:4:9: note: template is declared here
concept HasSize = requires(T obj)
        ^
z.cpp:15:33: error: expected ';' after top level declarator
void f6(HasSize const auto& arg) {} // error
                                ^
                                ;
3 errors generated.

Почему C ++ 20 не поддерживает "void f (Concept const auto &)"?

Ответы [ 2 ]

7 голосов
/ 09 апреля 2020

У вас неправильный синтаксис.

ограничения типа , такие как концепция HasSize здесь, принадлежат непосредственно перед указателем типа заполнителя , то есть до auto или decltype(auto):

void f6(const HasSize auto& arg) {}

См. [dcl.spe c .auto] черновика C ++ 20.

cv-qualifier s, такой как const, отделен от спецификатора типа заполнителя s, см. [decl.type] / 1 .


Как упомянуто @super в комментарии к вопросу decltype(auto) недопустимо в параметре функции. Так что это похоже на ошибку Clang, чтобы принять ее, см. [dcl.spe c .auto] / 2 , которая допускает только случай auto для placeholder- спецификатор типа в параметре функции.

5 голосов
/ 09 апреля 2020

Название концепции должно появиться прямо перед auto. Либо:

void f(const Concept auto&)

или:

void f(Concept auto const&)

оба действительны.

Мотивация была ( P1141 ):

Для простоты ограничению auto (или decltype(auto)) всегда предшествует ограничение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...