如何使编译器使用正确的模板专用化
How to make the compiler use the right template specialization?
请考虑以下简化版本的代码。我有一个模板类A
,一个模板函数Fill
,以及处理int
或char
等基本类型的函数的专用化,以及处理A
的另一个专用化:
#include <sstream>
#include <string>
#include <iostream>
template<size_t C>
class A
{
public:
A & operator=(std::string v) {
data[0] ='a';
return *this;
}
char data[C];
};
template<typename T> T Fill(std::string value, T default_value);
// Specialization for A<C>
template<size_t C>
A<C> Fill(std::string value, A<C> default_value)
{
if (value.empty())
return default_value;
A<C> result;
result = value;
return result;
}
// Specialization for int, double, char, etc
template<typename T>
T Fill(std::string value, T default_value)
{
if (value.empty())
return default_value;
T result;
std::istringstream(value) >> result;
return result;
}
void main()
{
int abc = Fill(/*Get a string somehow*/"123", 0); // OK
A<10> def;
def = std::string("111");
A<10> a;
a = Fill(/*Get a string somehow*/"abc", def); // OK
}
尽管我很惊讶编译器设法将参数与正确的模板专用化相匹配,但这工作正常。
问题伴随着一些typedef
,可以简化A<x>
的使用。这是一个简化版本:
typedef A<12> A12;
...
A<12> def12;
def12 = std::string("12");
A12 a12;
a12 = Fill(/*Get a string somehow*/"xyz", def12); // Not OK !
编译器没有检测到类型A12
实际上是A<12>
的,并且使用了错误的函数专用化,该函数不会编译,因为 istringstream 无法用 o perator>>
解析为A
。
如何使其使用正确的模板专业化?
模板专用化不是通过分配返回值的位置来推断的。 您必须显式实例化正确的版本:
a12 = Fill<A<12> >("xyz", def);
(或者你需要的任何东西...
typedef A<12> A12;
...
A12 a12;
a12 = Fill(/*Get a string somehow*/"xyz", def); // Not OK !
在此示例中,您尚未向我们展示 def
的类型 .假设它与前面的例子相同,即A<10>
,这肯定会失败。
在模板中,第二个参数的类型必须与返回类型匹配。试试这个:
typedef A<12> A12;
...
A12 a12;
A12 def12;
a12 = Fill(/*Get a string somehow*/"xyz", def12); // OK !
编译器未检测到类型 A12 实际上是 A<12>并且使用了错误的函数专用化
实际上,由于您在示例中传递了A<12> def;
(错误?),因此应该选择正确的重载(请参阅我对该问题的评论)。将结果分配给A12 a;
的事实不应影响重载解决。
如果您的意思相反(传递A12
并分配给任何内容),那么这可能是编译器的缺陷。这在这里可以正常工作。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 调用专用模板时出错"no matching function for call to [...]"
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- std::vector的包装器,使数组的结构看起来像结构的数组
- 模板专用化(按容器):value_type
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 找到两对数字,使它们的乘积的绝对差最小化
- C++:如何使函数只返回作为列表一部分的字符串
- 为什么使操作员成为新的专用会打破 std::shared_ptr?
- 如何使专用函数模板成为某个类的朋友?
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- C++ 使类的成员变量成为子类中的专用化
- 如何使指针指向模板化成员函数的专用变体
- 如果实例化,如何使模板化变量专用化在编译时失败
- 字符串到类型函数,模板专用化使调用统一
- 如何使模板成员函数专用化 std::vector<T>
- C++11编译器何时会使RVO和NRVO优于移动语义和常量引用绑定
- 如何使编译器使用正确的模板专用化
- 如何使模板函数专用化字符数组