4

当我有以下伪类时:

template <class T> class tmplClass
{
    void doSomething(T input);
};

当 sizeof(T) 大于系统架构时,void doSomething(T input)有没有办法改变。void doSomething(const T& input)

意味着,tmplClass<char> c;例如,当你有使用void doSomething(T input)时,当你有tmplClass<[another big class with lots of variables]>使用时void doSomething(const T& input)

  1. 我可以从中得到任何优化吗?
  2. 有什么我必须做的,或者 gcc 可以自动做吗
  3. 如果我必须做某事,怎么办?
4

2 回答 2

8

是的,很简单:

#include <type_traits>

template <typename T> struct Foo
{
    void do_something(typename std::conditional<(sizeof(T) > sizeof(void *)),
                                                 T const &, T>::type x)
    {
        // ... use "x"
    }

    // ...
};

您可能希望将结果类型分配给某个类型别名以便于重用。

正如@Yakk 所建议的那样,最好也添加std::is_trivially_copyable<T>::value条件以避免意外复制复制成本高昂或可能抛出的东西。

于 2013-05-15T20:54:15.107 回答
8

当然:

template<typename T, bool=true>
struct eff_arg {
  typedef T type;
};
template<typename T>
struct eff_arg<T, (sizeof(T)>sizeof(int))> {
  typedef T const& type;
};
// C++11 addition

template<typename T>
using EffArg = typename eff_arg<T>::type;

利用:

template <class T> class tmplClass
{
  // C++11
  void doSomething(EffArg<T> input);
  // C++03
  void doSomething(typename eff_arg<T>::type input);
};

并替换sizeof(int)为您想要用作“您想要作为参考而不是按值传递的点”的任何类型。

请注意,参数的大小是做出此决定的一种平庸的方式:一个极小的类(甚至比指针还小!)可能具有深度复制语义,其中一个大型结构在复制时会被复制。并且通常截断不应该是大小int或指针,而是大于那个,因为间接具有成本。

一个想法可能是只复制不管理资源且足够小的对象。 当您不需要数据副本时,可能是您在传递 a而不是 astd::is_trivially_copyable<T>::value && (sizeof(T) <= 2*sizeof(void*))之前应该进行的那种检查。TT const&

这导致以下情况:

template<typename T, bool=true>
struct eff_arg {
  typedef T const& type;
};
template<typename T>
struct eff_arg<T,
  std::is_trivially_copyable<T>::value
  && (sizeof(T)<=2*sizeof(void*))
> {
  typedef T type;
};
template<typename T>
using EffArg = typename eff_arg<T>::type;
于 2013-05-15T20:56:32.327 回答