2010-06-23 4 views
0

J'utilise Visual Studio 2008. J'ai cette classe:Comment cacher une fonction basée sur un paramètre de modèle

template <bool T1> 
class Foo { 
public: 
    void doSomething() {} 

    Foo<T1>& operator=(int a) { 
     doSomething(); 
     return *this; 
    } 
}; 

Mais je veux que la méthode operator= être cachée (en faisant simplement: return *this) si le paramètre de modèle T1 est faux.

J'ai besoin que pour les instances de Foo, les lignes:

Foo<false> foo; 
foo = 20; //this should give a compilation error 

donc j'ai essayé spécialisé la définition de classe:

template<> 
class Foo<false> { 
private: 
    Foo<false>& operator=(int a) { 
     return *this; 
    } 
}; 

Cependant, en faisant cela je perds la méthode doSomething() sur les instances qui sont Foo<false>, ce qui n'est pas ce dont j'ai besoin.

J'ai essayé de retirer le operator= avec boost :: enable_if, comme ceci:

typename boost::enable_if< 
    boost::mpl::bool_<T1> 
    , Foo<T1> 
>::type& 
operator=(int a) { 
    callProxy(); 
    return *this; 
} 

Mais cela me rend incapable d'avoir une classe comme les suivantes:

class Bar { 
public: 
    Foo<true> assignable; 
    Foo<false> unassignable; 
}; 

J'ai a également essayé de mettre les deux méthodes dans Foo et les supprimer avec boost::enable_if et boost::disable_if, comme ceci:

template <bool T1> 
class Foo { 
public: 
    void doSomething() {} 

    typename boost::enable_if< 
     boost::mpl::bool_<T1> 
     , Foo<T1> 
    >::type& 
    operator=(int a) { 
     doSomething(); 
     return *this; 
    } 

private: 
    typename boost::disable_if< 
     boost::mpl::bool_<T1> 
     , Foo<T1> 
    >::type& 
    operator=(int a) { 
     return *this; 
    } 
}; 

Ce qui n'a pas fonctionné aussi (je m'attendais à cela, mais cela valait la peine d'essayer).

Alors, est-il possible d'obtenir le comportement dont j'ai besoin, et si oui, comment pourrais-je le faire?

+1

Je suis confus pourquoi vous avez besoin d'un tel comportement. :) – GManNickG

Répondre

1

Vous pouvez affirmer statiquement la condition:

Foo<T1>& operator=(int a) { 
    BOOST_STATIC_ASSERT(T1); 
    doSomething(); 
    return *this; 
} 
+0

Cela a fonctionné comme un charme. Merci beaucoup. –

4

pourquoi ne pas simplement utiliser un if() standard?

if(T1) doSomething();

+0

Cela fonctionnerait, mais j'ai besoin de cela pour les instances de Foo appels pour l'opérateur = me donner une erreur de compilation. –

+1

@Edison: Alors ... alors votre code 'class Bar {public: Foo assignable; Foo inassignable; }; '** ne devrait pas ** fonctionner. – GManNickG

+2

Ok, alors ajoutez simplement static int dummy [T1]; dans le corps de l'opérateur = Lorsque T1 est faux, la taille du tableau sera zéro, ce qui n'est pas autorisé. Ou vous pouvez utiliser BOOST_STATIC_ASSERT. – zvrba

1

au lieu de l'enveloppe spéciale le cas false, vous pourriez cas spécial le cas true, et seulement inclure le operator= dans ce cas.

+0

Si je fais cela, le code suivant ne compilera pas: class Bar {public: Foo assignable; Foo inassignable; } –

Questions connexes