我试图通过禁止隐式类型转换(例如string-> bool)来实现模板类参数的类型检查,从而抛出编译错误。 具体方案如下:
#include <iostream>
#include <string>
using namespace std;
template <class T>
class myPair {
T a, b;
public:
myPair(T first, T second ) {
a = first;
b = second;
}
void test();
};
typedef myPair<bool> boolParm;
template<class T>
void myPair<T>::test() {
if(a == true) {
cout << "a is true" << endl;
} else {
cout << "a is false" << endl;
}
if(b == true) {
cout << "b is true" << endl;
} else {
cout << "b is false" << endl;
}
}
int main() {
boolParm myObj(false, "false");
myObj.test();
return 0;
}
上述场景的输出是不合需要的,因为用户可能无意中传递了两种不同的类型:bool和string并将第一个接收为false(因为bool传递正确)但第二个将为true(因为隐式类型不正确)从字符串转换为bool)。 我希望限制main()中的用户代码抛出编译错误并禁止string / int参数传递给构造函数。它应该只允许布尔。 我尝试使用重载的构造函数myPair(bool first,string second),但它不匹配,因为我猜是在调用构造函数之前发生了string-&gt; bool的隐式类型转换。 在这种情况下,是否有使用模板特化的解决方案? 任何帮助都非常感谢 感谢
答案 0 :(得分:1)
一种解决方法是添加模板化工厂函数来创建myPair。
template <typename T>
myPair<T> makeParam(T a, T b) {
return myPair<T>(a, b);
}
如果类型不匹配,则无法使用模糊模板参数T进行编译。您可以使用明确禁止某些类型的模板特化来扩展它。您的主要功能将类似于:
int main() {
boolParm myObj = makeParam(false, "false");
myObj.test();
return 0;
}
或者更改构造函数:
template <typename U, typename V>
myPair(U a, V b);
并根据需要进行专业化
这种专业化的一个例子:
template <class T>
class myPair {
T a, b;
public:
template <typename U, typename V> // generic version
myPair(U first, V second)
{
// intentionally fail to compile
static_assert(false, "don't support generic types");
}
template <> // template specialization
myPair(T first, T second)
{
// explicitly require exactly type T
a = first;
b = second;
}
};
答案 1 :(得分:0)
乍一看确实是奇怪的行为;但据我所知,你不能禁止这样做 - 不管是bool
这样的原始类型。
参数的隐式转换发生在你发表意见之前,似乎存在从char const *
到bool
的隐式原始类型转换。
参见例如另一个问题:Why does a quoted string match bool method signature before a std::string?