I need a way to decide whether to pass an arbitrary type T by copy or by const-reference (e.g., if T is small enough then copy if, otherwise pass it by const-reference). To avoid reinventing the wheel, I tried out Boost Call Traits.
As expected, primitive types are passed by value, and complex types like std::string
are passed by reference. However, tiny non-primitive types are also passed by reference, e.g., std::pair<char, char>
, which does not seem to be the best choice. I assumed that everything up to sizeof(void*)
would be passed by value.
Generally, the Boost libraries are of high quality, so maybe I am missing something.
Here is my test code:
#include <iostream>
#include <type_traits>
#include <tuple>
#include <boost/call_traits.hpp>
template <typename TYPE>
void test(const char* type_name)
{
typedef typename boost::call_traits<TYPE>::param_type T;
if(std::is_reference<T>::value)
std::cout << type_name << " is passed by reference (sizeof=" << sizeof(TYPE) << ")\n";
else
std::cout << type_name << " is passed by value (sizeof=" << sizeof(TYPE) << ")\n";
}
int main()
{
test<short>("short");
test<int>("int");
test<double>("double");
test<std::string>("std::string");
test<long long>("long long");
test<std::pair<int, int>>("std::pair<int, int>");
test<std::pair<short, short>>("std::pair<short, short>");
test<std::pair<char, char>>("std::pair<char, char>");
test<std::tuple<char, char>>("std::tuple<char, char>");
test<std::tuple<char, char, char, char>>("std::tuple<char, char, char, char>");
test<std::pair<long long, long long>>("std::pair<long long, long long>");
return 0;
}
And here are the results (Boost 1.50, g++ 4.7.2):
short is passed by value (sizeof=2)
int is passed by value (sizeof=4)
double is passed by value (sizeof=8)
std::string is passed by reference (sizeof=8)
long long is passed by value (sizeof=8)
std::pair<int, int> is passed by reference (sizeof=8)
std::pair<short, short> is passed by reference (sizeof=4)
std::pair<char, char> is passed by reference (sizeof=2)
std::tuple<char, char> is passed by reference (sizeof=2)
std::tuple<char, char, char, char> is passed by reference (sizeof=4)
std::pair<long long, long long> is passed by reference (sizeof=16)