2016-10-30 22 views
9

Czy można użyć typedef lub using, aby zadeklarować alias typu wewnątrz koncepcji, zgodnie z propozycją TS Koncepcji? Gdy próbuję coś jak następuje MWE, kod nie skompilować (z gcc 6.2.1 i przełącznikiem -fconcepts)C++ koncepcje deklaracja aliasu typu lite i type

#include <type_traits> 

template<typename T> 
concept bool TestConcept() 
{ 
    return requires(T t) 
    { 
     using V = T; 
     std::is_integral<V>::value; 
    }; 
} 

int main() 
{ 
    return 0; 
} 

wynikających błąd:

main.cpp: In function ‘concept bool TestConcept()’: 
main.cpp:8:9: error: expected primary-expression before ‘using’ 
     using V = T; 
     ^~~~~ 
main.cpp:8:9: error: expected ‘}’ before ‘using’ 
main.cpp:8:9: error: expected ‘;’ before ‘using’ 
main.cpp:4:14: error: definition of concept ‘concept bool TestConcept()’ has multiple statements 
concept bool TestConcept() 
       ^~~~~~~~~~~ 
main.cpp: At global scope: 
main.cpp:11:1: error: expected declaration before ‘}’ token 
} 
^ 
+0

Wygląda na to, że chciałbyś użyć 'typedef V T;', które byłoby alias 'T' na' V'. 'using' służy do wywoływania przestrzeni nazw lub określonych identyfikatorów z przestrzeni nazw. Oto przykład: http://stackoverflow.com/questions/10103453/is-typedef-inside-ofunction-body-a-bad-programming-practice –

+1

@JamesMurphy przepraszam, ale ponieważ C++ 11 możesz użyj słowa kluczowego 'using' do wyrażenia aliasów typu, tak jak przedtem z' typedef'. Oto odniesienie: http://en.cppreference.com/w/cpp/language/type_alias. – erikzenker

+0

@JamesMurphy przykład również kończy się niepowodzeniem z typedef, zasadniczo z tym samym komunikatem o błędzie. Jak powiedział erikzenker, składnia powinna być obecnie odpowiednikiem. – Slizzered

Odpowiedz

2

nr Według koncepcji TS wymóg jest:

requirement:
    simple-requirement
    type-requirement
    compound-requirement
    nested-requirement

Jeżeli proste wymaganie jest wyraźnego jon, po którym następuje wymóg typu ; i typu jest podobny do typename T::inner. Pozostałe dwa brzmią jak nazwa sugeruje.

Alias ​​typu jest deklaracją, a nie wyrażeniem, a więc nie spełnia wymogu wymagania.

+0

To wydaje mi się niepotrzebnie restrykcyjne. Czy wiesz, czy istnieje rozsądne obejście zamiast pisania tego samego skomplikowanego typu w kółko? – Slizzered

2

This feels unnecessarily restrictive to me. Do you know if there exists a reasonable workaround instead of writing the same complicated type over and over again?

Można odroczyć realizację ograniczeń do innej koncepcji, przekazując te typy jako parametry szablonu:

template<typename Cont, typename It, typename Value> 
concept bool InsertableWith = requires(Cont cont, It it, Value value) { 
    // use It and Value as much as necessary 
    cont.insert(it, std::move(value)); 
}; 

template<typename Cont> 
concept bool Insertable = requires { 
    // optional 
    typename Cont::const_iterator; 
    typename Cont::value_type; 
} && InsertableWith<Cont, typename Cont::const_iterator, typename Cont::value_type>; 

Jeśli rozważają to robić, proponujemy spróbować go na prostych przykładach przed podjęciem Decyzja. Sposób pisania pojęć i ograniczeń określa, w jaki sposób kompilator zgłasza błędy, i oczywiście posiadanie dobrych błędów jest dużą częścią tego, co sprawia, że ​​pojęcia są użyteczne. Ułatwianie pisania pojęć przy jednoczesnym utrudnianiu zrozumienia błędów nie jest kompromisem, który brałbym lekko.

Na przykład dlatego redundantnie dodano typename Cont::const_iterator; jako jawne ograniczenie. Daje to kompilatorowi możliwość zgłoszenia tego wymagania. Byłem także ostrożny przy wybieraniu nazwy InsertableWith jako nazwy pojęcia: mogłem po prostu łatwo przejść z detail::Insertable, ale błędy dotyczące zarówno Insertable, jak i detail::Insertable mogły w rezultacie być bardziej mylące.

Na koniec zauważ, że to wszystko zależy od jakości implementacji kompilatora, więc nie oczekuję, że jakiekolwiek podejście będzie na razie definitywne. Zachęcam do grania z tym Coliru demo.