J'ai le problème suivant (voir le code ci-dessous).C++ 11 méthode du modèle variadique complètement la méthode de la classe de base de l'ombre?
Dans une classe qui hérite d'une classe de base, je souhaite pouvoir avoir deux implémentations de operator()
. Celui qui prend des entiers, celui qui prend des "indices", voir la classe Index
simple. Le operator(ints...)
sera dans la classe des enfants, alors que je dois avoir la operator(Index...)
dans la classe parente (également avec différents types de retour.)
Le code ci-dessous n'est pas la conception exacte, mais un exemple de travail minimal expliquant le dernier problème .
Le problème est, si je mets operator(Index...)
dans la classe enfant, tout est bon. Si je le mets dans la classe de base, je reçois une erreur de compilation:
error: no match for call to ‘(Tensor<1, int>) (Index<'i'>&)’
quand je l'appelle vec(i)
et la fin de la main()
. Je comprends que le compilateur ne trouve pas la bonne méthode, mais pourquoi? Existe-t-il une règle de "masquage" associée aux modèles variés?
Merci!
#include <iostream>
#include <type_traits>
template<char i>
class Index{
public:
Index(){};
};
template<int order, typename T, class tensor_type>
class Tensor_traits{
public:
//// here, doesn't compile ! !
//template <char i>
//T&operator()(Index<i> &ii){
//std::cout << "puet" << std::endl;
//}
};
template<int order, typename T>
class Tensor : public Tensor_traits<order, T, Tensor<order, T>> {
private:
int data[3] = {1,2,3};
public:
Tensor(){};
template <typename... Idx>
typename std::enable_if<std::is_same<Idx...,int>::value
or std::is_same<Idx...,unsigned int>::value
or std::is_same<Idx...,size_t>::value, T&>::type
operator()(const Idx&... idx){
return data[0]; //dummy here, actually i do other stuff !
}
// here, works!
template <char i>
T&operator()(Index<i> &ii){
std::cout << "puet" << std::endl;
}
};
int main() {
Tensor<1,int> vec1;
std::cout<< vec1(1) << std::endl;;
Index<'i'> i;
vec1(i);
}
Moi, je fais d'abord 'en utilisant Base = Tensor_traits>;' puis 'en utilisant Base :: operator();'. Parce que mon cerveau n'est pas assez intelligent pour prouver instantanément 'Tensor_traits >' est juste la base de 'Tenseur ', et en le nommant 'Base' l'intention est plus claire. –
Yakk
@Yakk - également pour éviter la duplication de code dans le cas de 'using 'pour plusieurs méthodes de base? – max66
et dans les constructeurs etc. Si ce n'était pas le CRTP, ce que je fais habituellement est de le faire dans la liste d'arguments du template comme: ', class Base = Tensor_traits>', mais avec CRTP qui ne fonctionne pas . –
Yakk