6

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

就像是:

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

生成或:

void fun( A a ){
    ...
}

或者

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

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

4

2 回答 2

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 implementation - Boost.TypeTraits library

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

#include <boost/call_traits.hpp>

class A { ... };

void f(boost::call_traits<A>::param_type param);
于 2012-10-05T19:02:42.003 回答
6

你所描述的并不直接存在(至少,不是标准的)

编辑发现 OP 可能指的是什么:

0. 提升通话特性

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使用引用或数组类型。 在此处输入图像描述

您可能指的是两三 件事,AFAICT

1.rvalue参考资料

我可以想象你的意思是你可以优化移动语义。例如:

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 的回答,您可以使用元编程来实现这一点:

例如使用模板别名

#include <type_traits>

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

void f(check<A> param);
于 2012-10-05T18:59:16.543 回答