c++ - How to check if a template function was specialized? -
is there way establish in compile time if template function specialized?
for example, assume following function:
template<size_t n> void foo();
i want test if foo<42>
specialized. note declaration above doesn't contain default implementation.
i tried sfinae couldn't find condition on function compiler cannot deduce declaration.
any thoughts?
thanks
is there way establish in compile time if template function specialized?
with function... don't think so.
but if create functor, can add static const member (is_specialized
, in following example) can give information
#include <iostream> template <std::size_t n> struct foo { static constexpr bool is_specialized { false }; void operator() () const { std::cout << "- generic (" << n << ") foo struct" << std::endl; } }; template <> struct foo<42u> { static constexpr bool is_specialized { true }; void operator() () const { std::cout << "- specialized (42) foo struct" << std::endl; } }; int main() { foo<17u>()(); // print - generic (17) foo struct foo<42u>()(); // print - specialized (42) foo struct std::cout << foo<17u>::is_specialized << std::endl; // print 0 std::cout << foo<42u>::is_specialized << std::endl; // print 1 }
--- edit ---
following suggestion quentin (thanks again!) i've developed functor-based solution use something, detect if functor generic or specialize, added in generic functor. in case, type instead bool
constant.
template <std::size_t n> struct foo { // im_not_specialized added in generic version! using im_not_specialized = void; void operator () () const { std::cout << "- generic (" << n << ") foo struct" << std::endl; } }; template <> struct foo<42u> { void operator () () const { std::cout << "- specialized (42) foo struct" << std::endl; } };
this type can used via sfinae , propose example based on constexpr
isspecialized()
template function (with helper function)
template <typename f> constexpr bool isspecializedhelper (int, typename f::im_not_specialized const * = nullptr) { return false; } template <typename f> constexpr bool isspecializedhelper (long) { return true; } template <typename f> constexpr bool isspecialized () { return isspecializedhelper<f>(0); }
this require little more work isspecialized()
can reused different functors (im_not_specialized
type based)
the following full working example
#include <iostream> template <std::size_t n> struct foo { // im_not_specialized added in generic version! using im_not_specialized = void; void operator () () const { std::cout << "- generic (" << n << ") foo struct" << std::endl; } }; template <> struct foo<42u> { void operator () () const { std::cout << "- specialized (42) foo struct" << std::endl; } }; template <typename f> constexpr bool isspecializedhelper (int, typename f::im_not_specialized const * = nullptr) { return false; } template <typename f> constexpr bool isspecializedhelper (long) { return true; } template <typename f> constexpr bool isspecialized () { return isspecializedhelper<f>(0); } int main() { foo<17u>()(); // print - generic (17) foo struct foo<42u>()(); // print - specialized (42) foo struct constexpr auto issp17 = isspecialized<foo<17u>>(); constexpr auto issp42 = isspecialized<foo<42u>>(); std::cout << issp17 << std::endl; // print 0 std::cout << issp42 << std::endl; // print 1 }
Comments
Post a Comment