【发布时间】:2019-07-02 05:28:48
【问题描述】:
我有 2 个类,两个都有单参数模板化构造函数。一个用于整数类型的全部捕获,而在另一个类中,它用于绑定任何可迭代对象。对于每个类型的特定函数,我有两个重载。如果我用整数类型或字符串调用函数,或者至少对 一个 类有效的函数,我会收到关于调用歧义的错误。
#include <string>
class A {
public:
template <typename Iterable>
A(Iterable it) : s(it.begin(), it.end()) {}
private:
std::string s;
};
class B {
public:
template <typename Integer>
B(Integer i) : i(i + 1) {}
private:
int i;
};
void Use(A a)
{
// some thing
}
void Use(B b)
{
// some other thing
}
int main(void)
{
Use(0);
return 0;
}
编译器似乎对多态性集的研究不够深入,无法确定确实只有一种可能的解决方案。这可能是因为模板在函数重载之前被“解析”了吗?如何给编译器一些帮助?
【问题讨论】:
-
模板参数的名称只是一个名称。命名
Iteratable对编译器没有任何意义。为什么不向A的构造函数提供两个参数,即分别给出begin和end?许多标准容器都是这样做的。 (另外:支持子范围的容器也会变得更加灵活。) -
你也可以考虑
std::begin()和std::end()。这支持所有带有begin()和end()的容器,但不限于其他内容,例如纯 C 数组。 -
“编译器”不会查看函数的主体来确定它是否可以被调用。这也是一件好事,因为这样的事情会使 C++ 中的软件开发变得相当混乱。
-
C++20 的概念可能会有所帮助,目前,SFINAE 可能会有所帮助。
-
因为您在函数模板实现中犯的任何小错误默默地 使其无效并选择不同的重载。现在就去找你的错误。
标签: c++ templates constructor overloading overload-resolution