簡體   English   中英

條件typedef

[英]Conditional typedefs

如果我有一點點代碼......

template <typename _T>
class Foo
{
public:
    typedef const T& ParamType;
    void DoStuff(ParamType thingy);
};

如果sizeof(_T) <= sizeof(_T*)這可能是非最佳的。

因此,我想要一個條件typedef 如果_T的大小小於或等於指針的大小,則只需將其傳遞給值。 否則,通過const引用傳遞它。 這可能嗎? 我聽說所有這些關於模板的圖片都是完整的,但這讓我感到很傷心。

使用部分模板專業化很容易實現。

template< typename _T, bool _ByVal >
struct FooBase {
  typedef const _T& ParamType;
};

template< typename _T >
struct FooBase< _T, true > {
  typedef const _T ParamType;
};

template< typename _T, bool _ByVal = sizeof(_T) <= sizeof(void*) >
class Foo : public FooBase< _T, _ByVal > {
  typedef typename FooBase< _T, _ByVal >::ParamType ParamType;
  void DoStuff(ParamType thingy);
};

編輯根據傑夫的解決方案,確實應該比較sizeof(_T)sizeof(_T&)但我保留了原始的<= void*要求。

你可以做到這一點,但這有點棘手。

如果你的動機我在這里主要關注。 我知道您不希望按值傳遞大對象,但是對象是否大是無關緊要的 - 您真正想知道的是復制構造函數創建參數需要多長時間

作為一個具體的例子, std::vector的大小實際上非常小,因為它分配堆上的所有內存並且只需要一個指針。 但是,復制矢量需要更多時間。 像這樣的東西不是你可以真正包含在條件中的東西。

你最好的選擇是通過const &傳遞,以便你能夠覆蓋最糟糕的情況。 此外,我不能保證這一點,但我相信如果編譯器認為更有效,那么編譯器就足夠聰明地傳遞值。

template <class T, bool Smaller>
class BestArgumentPassingType {};

template <class T>
class BestArgumentPassingType<T, true> {
  public:
    typedef T Type;
};

template <class T>
class BestArgumentPassingType<T, false> {
  public:
    typedef const T& Type;
};

template <class T>
class ArgumentType : public BestArgumentPassingType<T, sizeof(T) < sizeof(T*)> {
};

struct B { double d; double d2; };
struct S { double d; };

class A {
  public:
    static void foo(ArgumentType<B>::Type big);
    static void bar(ArgumentType<S>::Type small);
};

int main()
{
  B b;
  S s;
  A::foo(b);
  A::bar(s);
  return 0;
}

像這樣。

您可以使用Boost呼叫特征

template <typename _T>
class Foo
{
public:
    void DoStuff(boost::call_traits<_T>::param_type thingy);
};

從文檔:

如果T是一個小的內置類型或指針,那么param_type被定義為T const,而不是T const&。

我知道這不是你要求的,但這是你的目標。 我會用另一種方法來實現這一點:通過引用傳遞類(包括結構和聯合),並按值傳遞其他所有內容。

template<typename>
struct tovoid { typedef void type; };

template<typename T, typename = void>
struct parm_type {
  typedef T type;
};

template<typename T>
struct parm_type<T, typename tovoid<int T::*>::type> {
  typedef T const& type;
};

template <typename T>
class Foo
{
public:
    typedef typename parm_type<T>::type ParamType;
    void DoStuff(ParamType thingy);
};

這實現了(在我看來)@Poita_所做的非常好的觀點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM