Beispiellösung
Content |
#ifndef DIM_HPP #define DIM_HPP #include <cstdlib> std::size_t dim(const char* const* argv) { std::size_t count = 0; while (*argv++) ++count; return count; } template<typename T, std::size_t N> constexpr std::size_t dim(const T (&)[N]) { return N; } template<typename T> auto dim(const T& container) -> decltype(container.size()) { return container.size(); } #endif
#include <iostream> #include <vector> #include "dim.hpp" int main(int argc, char** argv) { std::cout << "argv: " << dim(argv) << std::endl; std::vector<int> a = {1, 2, 3, 4}; std::cout << "a: " << dim(a) << std::endl; int b[] = {5, 6, 7}; std::cout << "b: " << dim(b) << std::endl; }
theon$ g++ -Wall -o testit testit.cpp theon$ ./testit 1 2 3 4 5 6 argv: 7 a: 4 b: 3 theon$
Wenn bei der ersten Funktion statt const char* const* argv nur const char** angegeben wird, dann würde das bedeuten, dass zwar beispielsweise für argv[0][0] nur ein Lesezugriff besteht, aber argv[0] verändert werden kann. Weil dann die Funktion theoretisch die Möglichkeit hätte einen Zeiger auf einer nur lesbare Zeichenkette bei argv[0] unterzubringen, führt das zu einem Problem beim Aufrufer, der davon ausgeht, dass die Möglichkeit eines Schreibzugriffs bei argv[0][0] gegeben ist.
theon$ g++ -Wall -c test-declarations.cpp test-declarations.cpp:8:24: error: array bound is not an integer constant before ']' token int array_like_a[dim(a)]; ^ theon$
Der Fehler rührt daraus, dass globale Arrays zur Übersetzzeit fest dimensioniert sein müssen. Da dim(a) auf der Variante beruht, die die size-Methode zur Laufzeit aufruft und daher nicht mit constexpr ausgezeichnet werden konnte, ist hier ein Fehler unvermeidlich.