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

Zhe*_*hen 6 c++ templates

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

就像是:

void fun( check<A> a ){
    ...
}
Run Code Online (Sandbox Code Playgroud)

生成或:

void fun( A a ){
    ...
}
Run Code Online (Sandbox Code Playgroud)

要么

void fun( A & a ){
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

Ros*_*ost 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);
Run Code Online (Sandbox Code Playgroud)

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

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

#include <boost/call_traits.hpp>

class A { ... };

void f(boost::call_traits<A>::param_type param);
Run Code Online (Sandbox Code Playgroud)


seh*_*ehe 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);
Run Code Online (Sandbox Code Playgroud)

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

例子

下表显示了call_traits对各种类型的影响,该表假定编译器支持部分特化:如果不支持,那么所有类型的行为方式与"myclass"的条目相同,并且不能使用call_traits使用引用或数组类型. 在此输入图像描述

您可以参照2两 3件事,AFAICT:

1. rvalue参考

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

struct Demo
{
     Demo(std::string&& tomove) : _s(std::move(tomove)) { }
   private:
     std::string _s;
};
Run Code Online (Sandbox Code Playgroud)

这条路,

 std::string a_very_large_string;
 Demo moving(std::move(a_very_large_string)); // prevents a copy
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

3.元编程:

基于@Rost的答案,您可以使用元编程来实现此目的:

例如,使用模板别名:

#include <type_traits>

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

void f(check<A> param);
Run Code Online (Sandbox Code Playgroud)