C++ 尝试使用类型未知的模板非类型参数
可能重复:C++ 尝试使用类型未知的模板非类型参数,c++,templates,c++11,traits,decltype,C++,Templates,C++11,Traits,Decltype,可能重复: 考虑以下工作代码: #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
考虑以下工作代码:
#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>();
}
#包括
模板结构特征{};
模板
结构特征
{
类型定义T类;
typedef A Arg;
};
模板
void生成器()
{
std::cout不幸的是,无法对非类型模板参数的类型进行类型推断。宏实际上是这里唯一的选项。我自己也花了一些时间尝试做类似的事情
我认为不使用函数名Class::foo
两次是不可能的。我的推理如下:
- 要获取
foo
的类型,我们必须使用decltype
或将foo
作为模板函数的参数
- 在上述任何一种情况下,
foo
(允许将其用作模板参数)的constexpr属性丢失
- 此外,我们不能在模板类或函数中“复制”
foo
,因为它将面临与上面相同的问题
- 结论:我们必须在外部范围内输入两次
foo
即使在C++11中,如果没有“脏”宏技巧,似乎也无法逃脱…无法完成。要拥有非类型模板参数,必须提供类型。因此,要么将生成器限制为一种特定类型,要么需要一个额外的参数(列表中的第一个)这是第二个参数的类型。现在,如果您不愿意将成员指针用作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 );
}
模板
结构生成器{
M T::*ptr;
生成器(mt::*ptr):ptr(ptr){}
};
模板
生成器createBuilder(M T::*ptr){
返回生成器(ptr);
}
int main(){
auto bld=createBuilder(&Class::member);
}
您不能执行模板无效生成器(t)
和生成器(&Class::foo)
?
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 );
}