Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++函数模板问题 我一直使用C,我有几个关于C++中函数模板的问题。 template <typename T> T max(T x, T y) { return (x > y) ? x : y; }_C++_Templates - Fatal编程技术网

C++函数模板问题 我一直使用C,我有几个关于C++中函数模板的问题。 template <typename T> T max(T x, T y) { return (x > y) ? x : y; }

C++函数模板问题 我一直使用C,我有几个关于C++中函数模板的问题。 template <typename T> T max(T x, T y) { return (x > y) ? x : y; },c++,templates,C++,Templates,我想声明它的一个变体,它使用CRecordset作为T,因此以下任一语句都是有效的: auto result = db.ExecuteSqlQuery<CCustomerRecordset>(L"SELECT ..."); auto result = db.ExecuteSqlQuery(L"SELECT ..."); 旧的C++使用了“类”,但是我们现在使用“类型名”。您仍然可以使用类,但建议使用typename。 是的,您可以通过专业化限制类型。。 模板T英尺x;//

我想声明它的一个变体,它使用CRecordset作为T,因此以下任一语句都是有效的:

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

auto result = db.ExecuteSqlQuery(L"SELECT ...");
旧的C++使用了“类”,但是我们现在使用“类型名”。您仍然可以使用类,但建议使用typename。 是的,您可以通过专业化限制类型。。 模板T英尺x;//<在一般情况下没有实现 允许使用模板T fooT x{return x;}/ 包括 包括 结构Cow{}; 样板 结构Moo { //默认为false 样板 静态空穴moo { 标准::cout 为什么有些示例在模板参数声明中使用typename,而其他示例使用class?有什么区别

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

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

是的,一种方法是依靠SFINAE放弃满足某些条件的类型的实例化,通常由std::enable_提供帮助,例如使用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中,将支持概念,允许编写

template<std::DerivedFrom<SomeBaseClass> T>
T max(T x, T y)
{
    return (x > y) ? x : y;
}
除了一个是模板化的,另一个不是,一个类有两个同名的方法吗

是的,这是可能的。在重载解析中,如果两个候选者都能很好地匹配,则首选非模板化的候选者

在这个特定的上下文中,类和类型名的意思完全相同,没有区别。类只是稍微短一点:-

在C++20之前,我们可以尝试使用复杂的技术限制模板参数。基本上,如果参数不满足某些条件,则会导致模板实例化失败。虽然这是一种非常强大的方法,但也有其缺点:编译时间增加,错误消息非常长且不清楚

在C++20中,我们有一个新的语言特性,名为,它的目的是以一种简单而直接的方式做同样的事情

是的,函数模板可以用常规函数重载。如果两者都匹配,则将选择常规函数。但是请注意,一般来说,这是一个非常复杂的主题

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

历史上,

简单模板只允许使用typename,模板参数应使用class:

template <template <typename> class C> void foo();
除了一个是模板化的,另一个不是,一个类有两个同名的方法吗

是的,那样的话,您可能会有几个重载

template <template <class> typename C> void foo();
template <int> void foo();
void foo();
或者更简单地说

template <typename T> void foo(T); // #1
void foo(int); // #2

// Note that foo<int> (#1 with T = int) is different than foo (#2)

关于第一个问题的更多详细信息,谢谢,但在我的例子中,我似乎无法得到最后一个答案的任何变体。我的方法是template std::unique_ptr ExecuteSqlQueryLPCTSTR pszSqlQuery,UINT nOpenType=AFX_DB_USE_DEFAULT_TYPE;,并且我想要一个使用CRecordset作为t并且不需要调用方提供类型参数的版本。我可能需要在这里问一个新问题。@JonathanWood:类似于?很有趣。事实上,当我将其修改为以下内容时,确实可以编译:std::unique_ptr executesqlquerylptstr pszSqlQuery,UINT nOpenType=AFX_DB_USE_DEFAULT_TYPE{return executesqlquerypszqlquery,nOpenType;}但是,我现在通过链接器得到了一个未解析的符号:错误LNK2019:未解析的外部符号public:class std::unique\u ptr\u thiscall CDatabaseCommon::ExecuteSqlQuerywchar\u t const*,unsigned intAnd,事实上,如果我使用模板语法,它在编译时不使用第二个方法。如果它像我认为的那样做,那就干净多了。但是我仍然获取链接器错误。看起来整个函数必须在头文件中声明。
template <typename T>
std::enable_if_t<some_trait<T>::value> foo();
template <template <class> typename C> void foo();
template <int> void foo();
void foo();
template <typename T> void foo(T); // #1
void foo(int); // #2

// Note that foo<int> (#1 with T = int) is different than foo (#2)