Quero distinguir contêineres unidimensionais e bidimensionais usando conceitos. Minha primeira tentativa foi a seguinte:
template<typename C>
concept Container1D = requires(C c) {
std::begin(c);
std::end(c);
c[0];
};
template<typename C>
concept Container2D = requires(C c) {
std::begin(c);
std::end(c);
c[0, 0]; // interpreted as comma-operator
};
Mas obviamente isso não funciona, porque a expressão 0, 0
é interpretada como um operador de vírgula e, portanto, o segundo conceito também corresponde a um contêiner unidimensional.
Existe uma maneira de exigir um bidimensional operator[a, b]
?
Problemas com operador de vírgula
Nem todo compilador oferece suporte a operadores subscritos multidimensionais ainda. No momento em que este artigo foi escrito, o suporte do compilador era este :
Como solução temporária, você pode usar
c.operator[](0, 0)
, que funciona desde que haja uma sobrecarga de subscritos multidimensionais na biblioteca padrão, mesmo que o recurso de linguagem principal ainda não seja compatível.Problemas com seus conceitos
Geralmente é melhor construir conceitos sobre outros existentes
concept
. Por exemplo, existestd::ranges::range
:Porém, esse conceito é realmente estranho porque
r[0]
implica que seu contêiner tenha acesso aleatório, então usar um requisito mais forte comostd::ranges::random_access_range
seria melhor: