array type deduction?



  • mit folgendem Code kann man die Größe eines C-Arrays per Deduktion ermitteln

    template<typename T, int Size>
    int array_size(T(&)[Size])
    {
      return Size;
    }
    
    int main()
    {
      int a[]={10,20,30};
      return array_size(a);
    }
    

    Frage:

    Ich würde gerne bei für eine Template-Funktion die Größe und Typ des Arrays zur Kompilezeit ermitteln - jemand eine Idee oder geht das nicht



  • ich brauchs für C++03



  • Welches Array? Kannst du deine Frage etwas genauer stellen?


  • |  Mod

    In C++03 wirste den Typ mittels BOOST_TYPEOF(*a) und die Größe mittels sizeof a / sizeof *a bekommen müssen.



  • @roflo

    das Beispiel ist doch eindeutig - oder?



  • @Arcoth

    kann auf dem System leider kein Boost einsetzen


  • |  Mod

    Gast3 schrieb:

    @Arcoth

    kann auf dem System leider kein Boost einsetzen

    Zeig ein Beispiel. Wie soll das Ganze zum Einsatz kommen?



  • ich will einfach ein C-Array in einen Slice umwandeln

    template<typename ValueType>
    class slice_T
    {
    private:
      ValueType* const _begin;
      ValueType* const _end;
    
    public:  
      typedef ValueType value_type;
    
      slice_T(ValueType* const p_begin, ValueType* const p_end):_begin(p_begin),_end(p_end)
      {
        assert(_begin <= _end);
      }
      //...
    };
    
    template<typename T, size_t Size>
    size_t array_size_T(T(&)[Size])
    {
      return Size;
    }
    
    template<typename ValueType, typename ArrayType>
    slice_T<ValueType> make_c_array_slice(ArrayType& p_array)
    {
      static_assert(sizeof(ValueType) == sizeof(p_array[0]), "not equal size");
      return slice_T<ValueType>(p_array, array_size_T(p_array));
    }
    
    int main()
    {
      const uint8_t data[]={0xAA,0xBB};
      auto slice = slice::make_c_array_slice<const uint8_t>(data);
    }
    

    und hab gedacht ich könnte noch irgendwie die make_c_array_slice<const uint8_t> - Angabe verzichten



  • keine Idee?



  • Du bist komisch, Gast3. Du fragst danach, wie man Typ und Größe eines C-Arrays zur Compilezeit ermitteln kann und beantwortest diese Frage selbst mit dem Funktionstemplate array_size_T .

    So etwas wie slice habe ich auch in meiner Sammlung:

    #include <cassert>
    #include <type_traits>
    #include <vector>
    #include <cstddef>
    
    #define REQUIRES_ARRAY_TYPE_CONVERTIBLE(U, T) \
        ,class = typename std::enable_if< \
            sizeof(T) == sizeof(U) && std::is_convertible<U*, T*>::value \
        >::type
    
    template<class T>
    class array_ref {
        T* base;
        std::size_t len;
        template<class> friend class array_ref;
    public:
        array_ref(T* base, std::size_t len)
        : base(base)
        , len(len)
        {}
    
        template<class U
            REQUIRES_ARRAY_TYPE_CONVERTIBLE(U, T)
        >
        array_ref(array_ref<U> const& x)
        : base(x.base)
        , len(x.len)
        {}
    
        std::size_t size() const { return len; }
    
        explicit operator bool() const {
            return len != 0;
        }
    
        T* begin() const { return base; }
        T* end() const { return base + len; }
    
        T& operator[](std::size_t i) const {
            assert(i < len);
            return base[i];
        }
    };
    
    template<class T, std::size_t N>
    array_ref<T> aref(T (&a)[N]) {
        return { a, N };
    }
    
    template<class T, std::size_t N>
    array_ref<const T> caref(const T (&a)[N]) {
        return { a, N };
    }
    
    template<class T, class A>
    array_ref<const T> aref(std::vector<T, A> const& v) {
        return { v.data(), v.size() };
    }
    
    template<class T, class A>
    array_ref<T> aref(std::vector<T, A> & v) {
        return { v.data(), v.size() };
    }
    
    template<class T, class A>
    array_ref<const T> caref(std::vector<T, A> const& v) {
        return { v.data(), v.size() };
    }
    
    #include <iostream>
    
    void show(array_ref<const int> ar) {
        for (int i : ar) {
            std::cout << i << '\n';
        }
    }
    
    int main() {
        int a[] = {1,2,3};
        show(aref(a));
        return 0;
    }
    


  • Du bist komisch, Gast3. Du fragst danach, wie man Typ und Größe eines C-Arrays zur Compilezeit ermitteln kann und beantwortest diese Frage selbst mit dem Funktionstemplate array_size_T.

    mir fehlt noch der Pointer auf das Array - dann wäres es perfekt
    und das Template so umzuschreiben das es geht bekomme ich nicht hin

    #include <stddef.h>
    #include <cassert>
    
    template<typename ValueType>
    class slice_T
    {
    private:
      ValueType* _begin;
      ValueType* _end;
    
    public:  
      typedef ValueType value_type;
    
      slice_T(ValueType* p_begin, const size_t& p_size):_begin(p_begin),_end(p_begin+p_size)
      {
      }
    };
    
    template<typename T, size_t Size>
    size_t array_size_T(T(&)[Size]){ return Size; }
    
    template<typename ValueType, typename ArrayType>
    slice_T<ValueType> make_c_array_slice_ALT(ArrayType& p_array)
    {
      static_assert(sizeof(ValueType) == sizeof(p_array[0]), "not equal size");
      return slice_T<ValueType>(p_array, array_size_T(p_array));
    }
    
    template<typename Type, size_t Size>
    void make_c_array_slice_BESSER(Type p_array[Size])
    {
      return slice_T<Type>(p_array, Size);
    }
    
    int a[]={1,2,3};
    
    int main()
    {
      auto s1 = make_c_array_slice_ALT<int>(a);
      auto s2 = make_c_array_slice_BESSER(a); 
    // note: candidate template ignored: 
    // couldn't infer template argument 'Size'
    
      return 0;
    }
    


  • ich schau mal deine Code noch genauer an - Danke



  • Danke für deine Hilfe - hab meinen Fehler gefunden



  • die letzte komische Frage

    warum muss man den Parametername als (&p_array) scheiben?

    warum geht nicht einfach Type p_array[Size]?

    ich kann gerade mit der Schreibweise gar nichts anfangen

    int NAME[3]
    int (&NAME)[3]

    das war der Fehler bei meinen Versuchen und hab es in deinem Source einfach Überlesen



  • http://www.cdecl.org/

    int &x[3];
    declare x as array 3 of reference to int

    int (&x)[3];
    declare x as reference to array 3 of int

    manchmal stell ich mich aber auch echt an



  • Gast3 schrieb:

    warum geht nicht einfach Type p_array[Size]?

    Weil das in einer Parameterliste zu nem Zeiger würde. Spezialregel die zur besseren Kompatibilität zu C aus C übernommen wurde.

    void foo(int x[123]);
    // ist das selbe wie
    void foo(int* x);
    

Anmelden zum Antworten