如何创建C ++模板以最佳方式传递值?

时间:2012-10-05 18:43:54

标签: c++ templates

我似乎记得我使用类型的大小来选择参数的值传递或引用传递。

类似的东西:

void fun( check<A> a ){
    ...
}

生成或:

void fun( A a ){
    ...
}

void fun( A & a ){
    ...
}

取决于类型A的大小和编译应用程序的体系结构。

2 个答案:

答案 0 :(得分:13)

在C ++ 11中,您可以使用std::conditional

#include <type_traits>

class A { ... };

typedef std::conditional<
   std::is_trivially_copyable<A>::value && sizeof(A) <= sizeof(int),
   A, const A&>::type AParam;

// Direct usage
void f(AParam param);

// Wrap into template class
template <typename T> struct check:
   std::conditional<std::is_arithmetic<T>::value, T, const T&> {};

void f(check<A>::type param);

对于C ++ 03编译器,您可以使用Boost实现 - Boost.TypeTraits library

正如@sehe所提到的,还有Boost.CallTraits library正确实现了所需的功能:

#include <boost/call_traits.hpp>

class A { ... };

void f(boost::call_traits<A>::param_type param);

答案 1 :(得分:6)

您所描述的内容不存在直接(至少不是标准

编辑找到OP可能正在提供的内容:

0。提升Call Traits

call_traits<T>::param_type可能是Op的想法/记住:

template<typename T> 
   using check = typename boost::call_traits<T>::param_type;

void f(check<A> param);
  

定义一种类型,表示将类型T的参数传递给函数的“最佳”方式。

     

<强>实施例

     

下表显示了call_traits对各种类型的影响,该表假定编译器支持部分特化:如果没有,那么所有类型的行为方式与“myclass”的条目相同,并且call_traits可以不能与参考或数组类型一起使用。   enter image description here

你可以指两个 三个的东西,AFAICT:

1。 rvalue引用

我可以想象你的意思是你可以优化移动语义。 E.g:

struct Demo
{
     Demo(std::string&& tomove) : _s(std::move(tomove)) { }
   private:
     std::string _s;
};

这样,

 std::string a_very_large_string;
 Demo moving(std::move(a_very_large_string)); // prevents a copy

2。完美转发:

完美转发与通用情况适用的原则相同:

#include <tuple>
#include <string>
#include <vector>

typedef unsigned int uint;

template <typename... T>
void AnotherDemo(T... args)
{
    std::tuple<T...> perfect(std::forward<T>(args)...); // optimal

    // more code using perfect, passing it by reference etc.
}

int main(int argc, const char *argv[])
{
    AnotherDemo(std::string("moved")); // moved
    AnotherDemo(42);                   // copied

    std::vector<double> v { 1,2,3 };
    AnotherDemo(v);                    // copied
    AnotherDemo(std::move(v));         // moved
}

3。元编程:

在@Rost的答案基础上,您可以使用元编程来实现这一目标:

E.g。使用模板别名

#include <type_traits>

template<typename T> 
   using check = typename boost::call_traits<T>::param_type;

void f(check<A> param);