2012-04-13 39 views
7

鑑於此模板:使用enable_if根據需要添加結構成員

template <class A> 
struct Something { 
    ... // members common to all template instantiations for all A types 
    SpecialType member; // but not this - I want this to be conditional... 
} 

...我想用「enable_if」有SpecialType成員有條件地存在;也就是說,只有當模板使用A = SpecialCase1或SpecialCase2類型實例化時。在其他所有情況下,我想讓SpecialType成員失蹤。

如果你想知道爲什麼,這是關於優化 - 即不在結構中攜帶無用的有效載荷。我是一個模板元編程的新手,但我知道我需要「enable_if」和兩個「is_same」 - 不知道如何確切如何,雖然...

編輯:這與通用C + +(即沒有提升細節)會是一個優點。

回答

5

嗯:使用基類。

struct Empty {}; 

struct SpecialTypeCnt { SpecialType member; }; 

template <typename A> 
struct Something: if_< /* cond */ , SpecialTypeCnt, Empty>::type { 
}; 

if_被定義爲:

template <typename, typename, typename E> struct if_ { typedef E type; }; 

template <typename T, typename E> 
struct if_<std::true_type, T, E> { typedef T type; }; 

(您也可以專注於一個boolean)

現在當然,你需要正確地表達你的病情。


話雖如此,你可能不應該只使用一個struct。相反,您應該使用class,它提供了需要在member上應用的操作。然後,您提供帶默認行爲的class Null和帶有member特定行爲的class SomeType

否則,你會重寫所需的任何地方「可能」修改member,它真的很快惱人。

+2

'if_'通常被稱爲'std :: conditional'。 – 2012-04-13 12:12:45

+0

@KerrekSB:啊,謝謝,我恐怕有點老前輩。在Boost MPL中它是'if_' :)我還沒有在C++ 11新庫中挖掘太多:/ – 2012-04-13 12:55:16

5

你不需要這個enable_if。專門爲特殊情況的結構,並保留其餘的默認實現:

template <class A> 
struct Something 
{ 
    // your default implementation 
}; 

template <> 
struct Something<SpecialCase1> 
{ 
    // your SpecialCase1 implementation 
}; 

template <> 
struct Something<SpecialCase2> 
{ 
    // your SpecialCase2 implementation 
}; 
+0

那倒導致重新請求所有常用字段和成員函數 - 我想避免這種情況(DRY)。 – ttsiodras 2012-04-13 11:59:25

+0

@ttsiodras - 使用組合或繼承,並按照我在成員或基類中建議的方式 – bobah 2012-04-13 12:50:43

2

爲了不重複的公共成員:

定義BaseSomething類:

template <class A> 
     struct BaseSomething { 
      ... // members common to all template instantiations for all A types 
       }; 

定義SpecialSomething類:

template <class A> 
      struct SpecialSomething { 
       SpecialType member; 
       ...//SpetialType related functionality 
        }; 

就定義了類:

template <class A> 
      struct Something :public BaseSomething<A>{ 

        }; 



    template<> 
    struct Something<SpecialCase1>:public BaseSomething<A>{ 
        SpecialSomething<SpecialCase1> special; 
         }; 


template<> 
struct Something<SpecialCase2>:public BaseSomething<A>{ 
       SpecialSomething<SpecialCase2> special; 
        }; 
+0

這是最接近我需要的 - 但肯定這比一行「enable_if」... – ttsiodras 2012-04-13 12:22:54

+2

如果verbose不適合你,那麼你至少應該仔細看看你使用C++語言的選擇。它有時可能非常冗長。 – 2012-04-13 12:32:29