Как передать массив объектов в качестве параметра в шаблон - PullRequest
0 голосов
/ 06 октября 2018

Я пытаюсь создать шаблон, который будет принимать ссылку на массив объектов в стиле C в качестве аргумента:

#include <iostream>

class A
{
public:
A(){}
};

template<int N, class A& obj> struct W {};

int main()
{
A b[5]; 
W<5,b> w; 
}

Но при компиляции кода я получаю ошибку:

$ c++ -std=c++11 -g try37.cpp
try37.cpp: In function 'int main()':
try37.cpp:14:5: error: the value of 'b' is not usable in a constant expression
 W<5,b> w;
     ^
try37.cpp:13:3: note: 'b' was not declared 'constexpr'
 A b[5];
   ^
try37.cpp:14:6: error: could not convert template argument 'b' to 'A&'
 W<5,b> w;
      ^
try37.cpp:14:9: error: invalid type in declaration before ';' token
 W<5,b> w;
         ^

Я пробовал много способов, но не смог решить проблему с компиляцией?Как решить то же самое?

Ответы [ 4 ]

0 голосов
/ 01 мая 2019
template < typename TElement, std::size_t NElement>
constexpr std::size_t sizeof_array( TElement const (&arr)[NElement] )
{
     (void)arr; // Unused, could have been anonymous
     return NElement;
}

template < typename TArray>
constexpr std::size_t sizeof_array2( const TArray& arr )
{
     return ( sizeof( arr ) / sizeof( arr[0] ) );
}

тогда в вашем коде:

char arr[] = "abcdef;
sizeof_array(arr); // C-styled array
sizeof_array2(arr);
0 голосов
/ 06 октября 2018

Редактировать: к ответу добавляется массив в стиле C.

Если вы пытаетесь получить struct W для контейнера объектов, вы можете использовать векторы, но.Я до сих пор не уверен, почему ты хочешь это сделать.

struct W
{
    template<typename Type, typename A> //constructor with a vector
    W(std::vector<Type,A> & vec)
    {
       //...
    }

    template<typename Type>
    W(int arraySize, Type & obj) //constructor with an array
    {
       //...

    }
};

int main()
{
    const int ArraySize = 5;
    A b[ArraySize];
    std::vector<A> vec;

    for(int i =0; i < 5; i++)
        vec.push_back(b[i]);

    W w(vec); //calling struct W constructor that takes a vector.
    W w2(ArraySize,b); //calling struct W constructor that takes c style array
    return 0;
}
0 голосов
/ 06 октября 2018

В вашем коде есть некоторые проблемы.

(1) если вы хотите передать ссылку на объект в качестве параметра шаблона, вы должны определить его как constexpr и присвоить ему внешний static связь (static не требуется, исправление от birdfreeyahoo (спасибо!)), Поэтому

constexpr A b[5]; 

int main ()
 {
   W<5,b> w; 
 }

(2), если вы хотите (массив в стиле C) constexpr A Объект (ы) инициализирован с конструктором по умолчанию, вы также должны сделать contexpr конструктором.

Итак

public:
constexpr A(){}

(3), если вы хотите, чтобы второй параметр шаблона для W являлся ссылкой на постоянный массив в стиле C, равный A с, где измерениеявляется первым параметром, синтаксис

template <int N, A const (& obj)[N]>
struct W
 { };

Таким образом, полная программа становится

class A
 {
   public:
      constexpr A ()
       { }
};

template <int N, A const (& obj)[N]>
struct W
 { };

constexpr A b[5]; 

int main ()
 {
   W<5, b> w; 
 }
0 голосов
/ 06 октября 2018

Прежде всего, вы сможете передать только 1 экземпляр A в шаблон.Измените его на A[n] obj Примечание. Он будет преобразован в указатель на A!

Во-вторых, передаваемый массив должен иметь статическую продолжительность хранения.Так что либо сделайте массив статическим, либо поместите его как глобальную переменную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...