C++模板参数仅限于类(而非基本类型)



是否可以指定一个永远不会与基本类型(如int(匹配的模板参数?我极力反对模棱两可的说法。例如:

template<class T> void Function(const T& x) { SetString(x.GetString()); };

只有当T中有一个方法GetString时,这才有效,但如果编译器看到这个函数,即使T只是int,它也会尝试使用它。

方法1

您可以使用std::enable_if,如下所示:

C++11

//this function template will not be used with fundamental types
template<class T> typename std::enable_if<!std::is_fundamental<T>::value>::type Function(const T& x) 
{ 
SetString(x.GetString()); 

};

演示

C++17

template<class T> typename std::enable_if_t<!std::is_fundamental_v<T>> Function(const T& x) 
{ 
SetString(x.GetString()); 

};

演示

方法2

我们可以使用SFINAE。在这里,我们使用decltype逗号运算符来定义函数模板的返回类型。

//this function template will work if the class type has a const member function named GetString
template <typename T> auto Function (T const & x) -> decltype( x.GetString(), void()) 
{ 
SetString(x.GetString());   
};

演示

在这里,我们使用尾随返回类型语法来指定函数模板的返回类型。

如果问题是int不支持GetString()方法,那么您可以在模板类型有一个GetString() const方法接受不带参数的调用时启用它,而不是为基本类型禁用该函数。

注意,GetString()必须是const,因为Function()接收到const引用,所以只有当GetString()const方法时,才能在Function()内部调用GetString()

下面是一个完整的编译示例。观察bar1bar2情况下的故障

#include <string>
void SetString (std::string const &) 
{ }
struct foo // class with a conformat GetString method
{ std::string GetString () const { return "abc"; } };
struct bar1 // class with a not conformant (not const) GetString method
{ std::string GetString () { return "123"; } };
struct bar2 // class with a not conformant (require a int) GetString method
{ std::string GetString (int) const { return "123"; } };
struct bar3 // class without a GetString method
{ };

template <typename T>
auto Function (T const & x) -> decltype( x.GetString(), void())
{ SetString(x.GetString()); }
int main()
{
Function(foo{}); // compile
// Function(bar1{}); // compilation error (GetString isn't const)
// Function(bar2{}); // compilation error (GetString require a int)
// Function(bar3{}); // compilation error (no GetString method)
// Function(0);      // compilation error (no GetString method)
}

相关内容

  • 没有找到相关文章

最新更新