意外的模板扣除

时间:2012-09-18 18:55:55

标签: c++ templates

template< typename T >
void addVarCB(const std::string &name,
              TwSetVarCallback setCallback, TwGetVarCallback getCallback,
              void * clientData, const std::string &def = "" );

template< class C, typename T >
void addVarCB(const std::string &name,
              C * _this, T(C::*getter)(void), const std::string &def = "");

以下代码将在运行时编译并崩溃:

bar_->addVarCB<MyClass, unsigned>("foo", this, &MyClass::MyClassFn, nullptr);

我实际上期望它根本不会编译,因为没有函数将其参数作为参数! (注意“MyClass,unsigned”是不必要的,但要清楚......)

2 个答案:

答案 0 :(得分:6)

可悲的是,std::string可以nullptr构建,见here,具体为(5)

basic_string( const CharT* s, // <== 'nullptr' matches here
              const Allocator& alloc = Allocator() );

注意:

  

5)使用s指向的以null结尾的字符串的内容构造字符串。字符串的长度由第一个空字符决定。 s不得为NULL指针。

答案 1 :(得分:5)

第一个评论是这与模板扣除无关。因为您提供的是模板参数,所以不会使用任何推论,而是使用第二个模板。

函数调用编译,因为从nullptrconst char*的转换可用于调用std::string的{​​{1}}构造函数。该构造函数的契约要求指针有效并指向空终止的字符序列,在代码中为false。