正在尝试使用具有未知类型的模板非类型参数

Trying to use a template non-type parameter with an unknown type

本文关键字:类型 类型参数 未知      更新时间:2023-10-16

可能重复:
是否可以模拟模板<自动X>?

考虑以下工作代码:

#include <iostream>
template<typename T> struct Traits {};
template<typename T, typename A>
struct Traits<void(T::*)(A)>
{
   typedef T Class;
   typedef A Arg;
};
template<typename T, typename U, void(T::*MemFun)(U)>
void Builder()
{
   std::cout <<  typeid(T).name() << std::endl;
   std::cout <<  typeid(U).name() << std::endl;
   std::cout <<  typeid(MemFun).name() << std::endl;
}
template<typename T, T arg>
void Builder()
{
   return Builder<Traits<T>::Class,Traits<T>::Arg,arg>();
}
class Class
{
public:
   void foo(int) { }
};
int main()
{
   Builder<decltype(&Class::foo), &Class::foo>();
}

我想做的是这样的事情,以获得相同的结果,而不使用宏。

int main()
{
   Builder<&Class::foo>();
}

我似乎无法创建一个将指针指向成员并推导类型的模板。有什么想法吗?指向成员的指针必须用作模板参数,而不是函数参数,因为它用于创建模板函数(未显示)。

无法完成。若要具有非类型模板参数,必须提供类型。因此,要么将生成器限制为一个特定类型,要么需要一个额外的参数(列表中的第一个),即第二个参数的类型。现在,如果您不愿意将成员指针用作constexpr。。。这很简单。

template <typename T, typename M>
struct Builder {
   M T::*ptr;
   Builder( M T::*ptr ) : ptr(ptr) {}
};
template <typename T, typename M>
Builder<T,M> createBuilder( M T::*ptr ) {
   return Builder<T,M>(ptr);
}
int main() {
   auto bld = createBuilder( &Class::member );
}

我自己也花了一些时间尝试做类似的事情。

如果不使用函数Class::foo的名称两次,我认为这是不可能的。我的理由如下:

  • 要获得foo的类型,我们必须使用decltype或将foo作为模板函数的参数
  • 在以上任何一种情况下,foo的constexpress(允许将其用作模板参数)都将丢失
  • 此外,我们不能在模板类或函数中"复制"foo,因为它将面临与上述相同的问题
  • 结论:我们必须在外部范围内键入两次foo

似乎没有"肮脏"的宏技巧是无法逃脱的,即使在C++11中也是如此…

不幸的是,没有办法对非类型模板参数的类型进行类型推导。宏实际上是这里唯一的选择。