正在尝试使用具有未知类型的模板非类型参数
Trying to use a template non-type parameter with an unknown type
可能重复:
是否可以模拟模板<自动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中也是如此…
不幸的是,没有办法对非类型模板参数的类型进行类型推导。宏实际上是这里唯一的选择。
相关文章:
- 如何使用非类型模板参数传入指向数组的指针
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 如何定义采用最通用数量和最类型的参数的函数
- 将类型声明为类型模板参数的模板参数的一部分是否合法?
- 是否可以在C++中有一个"generic"模板参数,该参数可以是非类型模板参数或类型?
- 推断指针非类型模板参数的类型
- 将空*参数转换为各种类型的参数是UB吗?
- 未命名的非类型模板参数有什么意义?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- Lambda可以用作非类型模板参数吗
- 类型为 "int*" 的参数与 C++ 中错误类型"int**"参数不兼容
- 基于类型作为参数的字符串表示形式具有不同返回类型的函数
- 具有"templated"返回类型和参数的函数指针
- 如何制作可以接受任何类型的参数的 std::函数和 lambda
- 指向(数据)成员的指针作为非类型模板参数,例如具有自动存储持续时间/无链接
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- C++ 类型的参数与 void (__cdecl*)(void) 类型的参数不兼容,当调用 std::atexit()
- 以特征类型作为参数的泛型函数回调
- 非类型模板参数