The template is wise, the lot bit (version dependent) continues in the constructor, although at compile time. Although all this is evaluated at compile time and therefore optimized, an empty constructor remains. If you add an empty constructor to the POD type, it will also not be memcpy'ed when used std::copy. Try the following:
#include <chrono>
#include <Eigen/Core>
#include <vector>
#include <iostream>
struct notpod
{
notpod() {}
double d[3];
};
struct pod
{
double d[3];
};
using Eigen::Vector3d;
int main(int argc, char** argv)
{
std::chrono::time_point<std::chrono::high_resolution_clock > start, end;
int sz = 20000000;
{
std::vector<pod> a(sz), b(sz);
start = std::chrono::high_resolution_clock ::now();
std::copy(a.begin(), a.end(), b.begin());
end = std::chrono::high_resolution_clock ::now();
std::cout << " POD vector copy took " << (std::chrono::duration<double>(end - start)).count() << " seconds.\n";
}
{
std::vector<notpod> na(sz), nb(sz);
start = std::chrono::high_resolution_clock ::now();
std::copy(na.begin(), na.end(), nb.begin());
end = std::chrono::high_resolution_clock ::now();
std::cout << " NotPOD vector copy took " << (std::chrono::duration<double>(end - start)).count() << " seconds.\n";
}
{
std::vector<Vector3d> a3(sz), b3(sz);
start = std::chrono::high_resolution_clock ::now();
std::copy(a3.begin(), a3.end(), b3.begin());
end = std::chrono::high_resolution_clock ::now();
std::cout << "Vector3d vector copy took " << (std::chrono::duration<double>(end - start)).count() << " seconds.\n";
}
return 0;
}
:
POD 0.135008 .
NotPOD 0.35202 .
Vector3d 0.35302 .