键入检查模板类参数

时间:2013-10-07 06:20:56

标签: c++ templates typechecking

我试图通过禁止隐式类型转换(例如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的隐式类型转换。 在这种情况下,是否有使用模板特化的解决方案? 任何帮助都非常感谢 感谢

2 个答案:

答案 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?