0

我试图通过禁止隐式类型转换(如 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;
}

上述场景的输出是不可取的,因为用户可能无意中传递了 2 种不同的类型:bool 和 string,并且将第一个接收为 false(因为传递为 bool,所以正确)但第二个将是 true(因为从 string 进行隐式类型转换,所以不正确布尔值)。我希望限制 main() 中的用户代码引发编译错误并禁止字符串/int 参数传入构造函数。它应该只允许布尔。我尝试使用重载的构造函数 myPair(bool first, string second) 但它不匹配,因为我猜 string->bool 的隐式类型转换发生在调用构造函数之前。在这种情况下是否有使用模板专业化的解决方案?非常感谢任何帮助谢谢

4

2 回答 2

1

一种解决方法是添加一个模板化工厂函数来创建 myPair。

template <typename T>
myPair<T> makeParam(T a, T b) {
    return myPair<T>(a, b);
}

如果类型不匹配,这将无法使用模棱两可的模板参数 T 进行编译。您可以使用模板特化来扩展它,明确禁止 T 的某些类型。您的 main 函数将如下所示:

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;
    }
};
于 2013-10-07T06:41:11.173 回答
0

乍一看确实很奇怪;但据我所知,您不能禁止这样做 -bool无论如何,对于原始类型来说不是这样。

参数的隐式转换发生在您获得发言权之前,并且似乎存在从char const *to的隐式原始类型转换bool

另请参见其他问题:为什么引用的字符串在 std::string 之前匹配 bool 方法签名?

于 2013-10-07T06:35:59.310 回答