Elegant way to initialize non-static array member (2)

M

mathieu

Hi there,

I was recently help for an issue with the following code:

template <typename T, unsigned int N>
struct Functor
{
T values[N];
};

#include <algorithm>
template <typename T, unsigned int N>
Functor<T,N> makeFunctor(T const (&a)[N])
{
Functor<T,N> f;
std::copy(a, a + N, f.values);
return f;
}

int main()
{
const double v[] = {0, 1, 4, 9, 16, 25, 36 };
const unsigned int N = sizeof(v) / sizeof(v[0]);

Functor<double,N> f = makeFunctor(v);

return 0;
}


Is this completely equivalent to doing (*). or am I garantee that
template will be inlined (without explicit inline keyword).

Thanks
-Mathieu

(*)
#include <algorithm> // std::copy

template <typename T, unsigned int N>
struct Functor
{
Functor(T const (&a)[N])
{
std::copy(a, a+N, values);
}

T values[N];
};

int main()
{
const double v[] = {0, 1, 4, 9, 16, 25, 36 };
const unsigned int N = sizeof(v) / sizeof(*v);
Functor<double,N> f = v;

return 0;
}
 
V

Victor Bazarov

mathieu said:
Hi there,

I was recently help for an issue with the following code:

template <typename T, unsigned int N>
struct Functor
{
T values[N];
};

#include <algorithm>
template <typename T, unsigned int N>
Functor<T,N> makeFunctor(T const (&a)[N])
{
Functor<T,N> f;
std::copy(a, a + N, f.values);
return f;
}

int main()
{
const double v[] = {0, 1, 4, 9, 16, 25, 36 };
const unsigned int N = sizeof(v) / sizeof(v[0]);

Functor<double,N> f = makeFunctor(v);

return 0;
}


Is this completely equivalent to doing (*). or am I garantee that
template will be inlined (without explicit inline keyword).

Thanks
-Mathieu

(*)
#include <algorithm> // std::copy

template <typename T, unsigned int N>
struct Functor
{
Functor(T const (&a)[N])
{
std::copy(a, a+N, values);
}

T values[N];
};

int main()
{
const double v[] = {0, 1, 4, 9, 16, 25, 36 };
const unsigned int N = sizeof(v) / sizeof(*v);
Functor<double,N> f = v;

return 0;
}

No, it's not. You had a POD class, and if you add a user-defined
constructor to it, 'Functor' stops being a POD class. That was
the only reason I suggested a stand-alone function.

If you don't care for 'Functor' to be a POD class, the constructor
solution is better.

V
 
M

mathieu

mathieu said:
Hi there,
I was recently help for an issue with the following code:
template <typename T, unsigned int N>
struct Functor
{
T values[N];
};
#include <algorithm>
template <typename T, unsigned int N>
Functor<T,N> makeFunctor(T const (&a)[N])
{
Functor<T,N> f;
std::copy(a, a + N, f.values);
return f;
}
int main()
{
const double v[] = {0, 1, 4, 9, 16, 25, 36 };
const unsigned int N = sizeof(v) / sizeof(v[0]);
Functor<double,N> f = makeFunctor(v);
return 0;
}
Is this completely equivalent to doing (*). or am I garantee that
template will be inlined (without explicit inline keyword).

(*)
#include <algorithm> // std::copy
template <typename T, unsigned int N>
struct Functor
{
Functor(T const (&a)[N])
{
std::copy(a, a+N, values);
}
T values[N];
};
int main()
{
const double v[] = {0, 1, 4, 9, 16, 25, 36 };
const unsigned int N = sizeof(v) / sizeof(*v);
Functor<double,N> f = v;
return 0;
}

No, it's not. You had a POD class, and if you add a user-defined
constructor to it, 'Functor' stops being a POD class. That was
the only reason I suggested a stand-alone function.

If you don't care for 'Functor' to be a POD class, the constructor
solution is better.

Ok thanks. As for the issue with the 'return' in your makeFunctor I
was told that c++ compiler can implement "Named Return Value
Optimization" (NRVO) to avoid the extra copy.

-Mathieu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top