为每个模板(int)形参向类中添加方法
Add method to class for each template (int) parameter
我有一个数列,它不应该是连续的。比如5,2,3,我想让它们映射到数组索引(5 -> 0,2 -> 1,3 -> 2)。下面是我的代码,对我来说似乎是正确的。
template<size_t Index, int ...Values>
struct indexer;
template<size_t Index>
struct indexer<Index> { };
template<size_t Index, int T, int ...Rest>
struct indexer<Index, T, Rest...> :
public indexer<Index + 1, Rest...>
{
template<int Value> size_t get();
template<> size_t get<T>() { return Index; }
};
// this class (should) maps Values... to 0,1,2...
template<int ...Values>
struct mapper :
public indexer<0, Values...>
{ };
现在我可以调用:
mapper<5, 2, 3> m;
m.get<5>(); // returns 0 as expected
m.get<2>(); // does not compile
错误1错误LNK2019:未解析的外部符号"public: unsigned int __thiscall indexer<0,5,2,3>::get<2>(void)"($get@$01@?$indexer@$0A@$04$01$02@@QAEIXZ)在函数_main C:…ATL.Consolemain中引用。obj ATL。控制台
谁能解释一下怎么回事?似乎m没有函数get<2>(),但为什么?c++ 11不允许在类范围内显式特化。这个声明:
template<int Value> size_t get(); // primary template
template<> size_t get<T>() { return Index; } // <-- this one
是非法的,由于语言扩展,它只在msvc++中被接受。
此外,它可能不做你想要的:
template<int Value> size_t get();
声明了一个成员函数模板。通过声明名称为get
的成员,可以隐藏在任何基类中声明的所有具有相同名称的成员。
template<> size_t get<T>() { return Index; }
表示(如果合法的话):如果重载解析选择了前一行声明的主模板get
,并且传递给该成员函数模板的模板形参等于类模板的模板形参T
,那么您应该使用以下函数的定义(而不是主成员函数模板的定义)
函数模板的显式专门化为函数模板提供了另一种定义。它本身不是一个函数(模板),也不参与(自身)重载解析。
当然,如果重载解析选择了这个成员函数模板,但是模板形参条件不成立(当value != T
时=),则使用主模板的定义。但是主模板没有定义!因此出现了链接器错误。
你可以这样做:
#include <cstddef> // for std::size_t
#include <type_traits> // for std::integral_constant
template<size_t Index, int ...Values>
struct indexer;
template<size_t Index>
struct indexer<Index>
{
// provide a dummy to allow simple overloading via a using-declaration
// if you see a linker error here, then Value could not be found
template<int Value>
size_t get(std::integral_constant<int, Value>);
// it would be nice to provide a definition for the template above,
// containing a `static_assert` for a nice compile-time error message,
// but I'm not sure on what to assert.
};
template<size_t Index, int T, int ...Rest>
struct indexer<Index, T, Rest...> :
public indexer<Index + 1, Rest...>
{
template<int Value>
size_t get()
{
return get(std::integral_constant<int, Value>());
}
// a using-declaration to allow overloading
using indexer<Index + 1, Rest...>::get;
size_t get(std::integral_constant<int, T>)
{ return Index; }
};
// this class (should) maps Values... to 0,1,2...
template<int ...Values>
struct mapper :
public indexer<0, Values...>
{};
当然,现在有许多冗余的get(void)
成员函数模板(顺便说一句,所有这些成员函数都可以是static
)。因此,您可以将其移动到mapper
中,甚至可以提供非成员函数。
相关文章:
- 使用mem_fun_ref if成员函数需要多个形参
- 通过类的模板形参特化成员模板结构
- 非类型引用形参/实参
- 哪个模板形参在boost::shared_ptr构造函数中使用一个原始指针
- 如何确保迭代器模板形参与模板类的模板形参具有相同的数据类型
- 如何在编译时通过模板形参默认值的名称/指针获取函数的类型
- c++:候选模板被忽略:模板形参显式指定的参数无效
- c++中作为形参的指针
- 哪种方法更适合为函数提供编译时间常数?函数实参与模板形参
- 包含void*结构的函数的Const正确性和形参
- 传递boost::函数,该函数接受一个模板实参作为默认为NULL的形参
- 将右值引用形参强制转换为右值引用
- 给引用形参赋值使对象无效
- 当实参是初始化列表而形参是引用时,重载解析
- const整型模板形参的条件
- 使用作为模板形参提供的基类成员,不带限定符
- 模板类的不同返回类型取决于类的形参
- c++ const函数形参.有没有一种方法可以只声明函数的单个签名?
- c++ 03:是否有一种方法可以使一个类型每次被包含在模板形参中时都会编译成不同的类型?
- 为每个模板(int)形参向类中添加方法