déclare juste la fonction de modèle et ne définissent pas, définissent alors deux spécialisations:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc();
template <>
Eigen::Matrix<double, 2, 1> myFunc<2>()
{
return ExternalLibrary::generate_Vector_2d();
}
template <>
Eigen::Matrix<double, 3, 1> myFunc<3>()
{
return ExternalLibrary::generate_Vector_3d();
}
Le compilateur, alors qu'il éliminera le code mort comme une optimisation, doit vérifier la validité du code mort de toute façon, ce qui signifie qu'il doit s'assurer que le type de retour de ExternalLibrary::generate_Vector_3d()
peut être converti en Eigen::Matrix<double, 2, 1>
, même s'il peut être prouvé que cette déclaration de retour ne peut pas être exécutée. Parce que cette conversion n'est pas autorisée, vous obtenez une erreur de compilation.
En séparant les deux déclarations de retour dans des spécialisations différentes, vous éliminez ce problème, car il élimine la déclaration return ExternalLibrary::generate_Vector_3d();
d'une fonction qui pourrait retour autre chose qu'un Eigen::Matrix<double, 3, 1>
.
Notez que l'utilisation myFunc()
avec un autre nSize
que 2 ou 3 provoquera une erreur de lien. Nous pouvons passer cette erreur de compilation en fournissant un corps qui ne parviendra pas à instancier, mais (apparemment) dépend de nSize
afin que le compilateur ne tentera pas de instancier avant qu'il ne soit utilisé:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc()
{
// With C++11, the following line provides a more useful diagnostic. If
// you don't have C++11 support, remove it and the bad return statement
// will do the job, albeit with a more cryptic error message.
static_assert((static_cast<void>(nSize), false), "Invalid template parameter nSize");
return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
}
Cela fournira un diagnostic indiquant l'utilisation incorrecte de myFunc()
. Par exemple, sans support 11 C++ vous verriez quelque chose comme:
main.cpp:12:12: error: cannot cast from type 'int' to pointer type 'class INVALID_NSIZE_PARAMETER **********'
return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:29:5: note: in instantiation of function template specialization 'myFunc<4>' requested here
myFunc<4>();
^
pourquoi ne pas [se spécialiser pleinement] (http://en.cppreference.com/w/cpp/language/template_specialization) le modèle de func? –