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.