c++ - 如何检查功能模板是否已专门化?

标签 c++ templates template-meta-programming template-specialization

有没有办法在编译时确定某个函数模板是否特化?

例如,假设有以下函数模板:

template<size_t N>
void foo();

我想测试是否foo<42>是专门的。请注意,上面的声明不包含任何默认实现。

我尝试了 SFINAE,但找不到编译器无法从其声明中推断出的函数条件。

最佳答案

Is there a way to establish in compile time if a certain template function was specialized?

有一个函数……我不这么认为。

但是如果你创建一个仿函数,你可以添加一个静态常量成员(is_specialized,在下面的例子中),它可以给你这个信息

#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
 }

--- 编辑 ---

根据 Quentin 的建议(再次感谢!)我开发了另一种基于仿函数的解决方案,该解决方案使用某些东西来检测仿函数是通用的还是专门的,仅在通用仿函数中添加。在这种情况下,类型而不是 bool 常量。

template <std::size_t N>
struct foo
 {
   // im_not_specialized is added only in the 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; }
 };

这种类型可以通过 SFINAE 使用,我提出了一个基于 constexpr isSpecialized() 模板函数(带有辅助函数)的示例

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); }

这需要做更多的工作,但是 isSpecialized() 可以与不同的仿函数重用(基于 im_not_specialized 类型)

下面是一个完整的工作示例

#include <iostream>

template <std::size_t N>
struct foo
 {
   // im_not_specialized is added only in the 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
 }

关于c++ - 如何检查功能模板是否已专门化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43072709/

相关文章:

c++ - 约束成员模板的外定义规则是什么?

c++ - C++20 NTTP 和类型之间的转换

C++ 从空指针调用非虚非静态方法,不访问成员 : is this guaranteed to work?

c++ - 具有未指定操作数的C++计算器

python - 如何统计模板匹配检测到的对象数量?

c++ - 有没有办法帮助编译器处理复杂的参数推导?

c++以编程方式创建模板化对象

c++ - 正则表达式:boost::xpressive 与 boost::regex

c++ - 使用 BFS 在 Boost BGL 图中查找所有可达的顶点

c++ - 将 boost::any 转换为 boost::variant 的通用函数