意外的模板扣除

aCu*_*ria 1 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 = "");
Run Code Online (Sandbox Code Playgroud)

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

bar_->addVarCB<MyClass, unsigned>("foo", this, &MyClass::MyClassFn, nullptr);
Run Code Online (Sandbox Code Playgroud)

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

Xeo*_*Xeo 6

可悲的是,std::string可以构建,具体来说nullptr,请参见此处(5):

basic_string( const CharT* s, // <== 'nullptr' matches here
              const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)

注意:

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


Dav*_*eas 5

第一个评论是这与模板推断无关.因为您提供模板参数,所以不使用任何推论,并使用第二个模板.

函数调用编译为存在从转换nullptrconst char*可以用来调用std::string,需要一个构造函数const char*.该构造函数的契约要求指针有效并指向空终止的字符序列,在您的代码中为false.