首页 > 解决方案 > C++ 函数模板问题

问题描述

我一直在使用 C#,我有几个关于 C++ 中的函数模板的问题。

template <typename T>
T max(T x, T y)
{
    return (x > y) ? x : y;
}
  1. 为什么在模板参数声明中有些示例使用typename而其他示例使用?class有什么不同?
  2. 有没有办法限制T特定类型或从特定类型派生的类型?
  3. 一个类有没有办法拥有两个同名的方法,除了一个是模板化的,另一个不是?

更新:

我感谢所有答案,但其中一些包含我在尝试将它们应用于我的代码时不会编译的示例。

为了澄清问题3,我有以下方法:

template<typename T>
std::unique_ptr<T> ExecuteSqlQuery(LPCTSTR pszSqlQuery, UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE);

我想声明一个使用CRecordsetas的变体T,以便以下任一语句有效:

auto result = db.ExecuteSqlQuery<CCustomerRecordset>(L"SELECT ...");

auto result = db.ExecuteSqlQuery(L"SELECT ...");

标签: c++templates

解决方案


为什么在模板参数声明中有些示例使用typename而其他示例使用?class有什么不同?

两者在模板参数声明中没有区别,但是在其他上下文中它们都有额外的单独含义。egtypename用于将依赖名称标记为类型名称,并class用于引入类声明。

有没有办法将 T 限制为特定类型,或从特定类型派生的类型?

是的,一种方法是依靠 SFINAE 丢弃满足某些条件的类型的实例化,通常由 促进std::enable_if,例如(使用 C++14):

template<typename T, typename = std::enable_if_t<std::is_base_of_v<SomeBaseClass, T>>
T max(T x, T y)
{
    return (x > y) ? x : y;
}

在即将到来的 C++20 中,将支持 Concepts,它允许人们编写

template<std::DerivedFrom<SomeBaseClass> T>
T max(T x, T y)
{
    return (x > y) ? x : y;
}

一个类有没有办法拥有两个同名的方法,除了一个是模板化的,另一个不是?

是的,这是可能的。在重载解决方案中,如果两个候选者都匹配得很好,那么非模板化的候选者将是首选。


推荐阅读