Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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++_Templates - Fatal编程技术网

C++ 定义函数模板

C++ 定义函数模板,c++,templates,C++,Templates,我想知道下面示例中的表达式cT::value\u type告诉编译器什么?我可以写任何我不会代替wordvalue\u type的内容-它无论如何都会构建。看起来代码试图告诉编译器“cT类型应该有一些属性(可能是向量成员,但在模板定义中不可见),该类型将用于第二个函数参数”。我的理解离现实有多远 编译器如何知道两个参数都应作为字符串: joinContainer(s1, ':'); 在编译的地方,我会期待类似的东西 joinContainer<string,string>(s1,

我想知道下面示例中的表达式
cT::value\u type
告诉编译器什么?我可以写任何我不会代替word
value\u type
的内容-它无论如何都会构建。看起来代码试图告诉编译器“
cT
类型应该有一些属性(可能是向量成员,但在模板定义中不可见),该类型将用于第二个函数参数”。我的理解离现实有多远

编译器如何知道两个参数都应作为字符串:

joinContainer(s1, ':'); 
在编译的地方,我会期待类似的东西

joinContainer<string,string>(s1, ':'); 
joinContainer(s1,,:');
或者可能是什么事件

<string>joinContainer<string,string>(s1, ':'); 
joinContainer(s1,,:');
全部代码:

// join.cpp by Bill Weinman <http://bw.org/>
#include <iostream>
#include <vector>
using namespace std;

template<typename cT, typename retT = cT, typename sepT = decltype(cT::value_type)>
retT joinContainer(const cT & o, const sepT & sep) {
    retT out;

    auto it = o.begin();
    while(it != o.end())
    {
        out += *it;
        if(++it != o.end()) out += sep;
    }
    return out;
}

int main( int argc, char ** argv ) {
    string s1("This is a string");
    string s2("This is also a string");
    string s3("Yet another string");

    // join the characters of a string


    cout << joinContainer<string, string>(s1, ':') << endl;

    // join strings from a vector, returning a string
    vector<string> vs({s1, s2, s3});
    cout << joinContainer<vector<string>, string>(vs, ", ");
    return 0;
}
//Bill Weinman编写的join.cpp
#包括
#包括
使用名称空间std;
模板
翻新集装箱(施工cT&o、施工九月和九月){
脱胶;
自动it=o.begin();
while(it!=o.end())
{
out+=*它;
如果(++it!=o.end())输出+=sep;
}
返回;
}
int main(int argc,字符**argv){
字符串s1(“这是一个字符串”);
字符串s2(“这也是一个字符串”);
字符串s3(“另一个字符串”);
//连接字符串的字符

cout编译器从2.function参数获取sepT模板参数,因此它可能从未使用默认参数(
cT::value\u type
),因此它可能从未实例化使用第三个模板参数的默认值的模板

至于你的第二个问题,为什么你可以写
joinContainer(s1,:”;
,它可以工作。编译器拥有它所需要的所有信息。1.和3.模板参数是从函数参数推导出来的。2.模板参数没有指定,但在定义中有一个默认参数,因此编译器使用它

joinContainer(s1, ':'); 
cT - type std::string (deduced from s1)
retT - type std::string (default value used, which is the same as cT)
sepT - type const char (deduced from ':')

joinContainer<string,string>(s1, ':'); 
cT - type std::string (because you specified in the template parameters)
retT - type std::string (because you specified in the template parameters)
sepT - type const char (deduced from ':')
note: if s1 would not be of type std::string there would be a compiler error

<string>joinContainer<string,string>(s1, ':'); 
Will not compile.
joinContainer(s1,,:');
cT类型std::string(从s1推导)
retT-type std::string(使用默认值,与cT相同)
sepT-type常量字符(由“:”推导而来)
joinContainer(s1,,:');
cT-type std::string(因为您在模板参数中指定了)
retT-type std::string(因为您在模板参数中指定了)
sepT-type常量字符(由“:”推导而来)
注意:如果s1不是std::string类型,则会出现编译器错误
joinContainer(s1,,:');
不会编译。

这个例子似乎有点不合逻辑。基本上是这样的:

template<typename T = Foo>
void f(const T & x)
{
    // print x, whatever...
}
也就是说,您必须始终传递一个参数,
T
将始终被推导,因此永远不会使用
Foo

(好的,您也可以强制使用模板参数,比如
f(obj);
,但是
Foo
仍然不会被使用,您无论如何都不应该这样做。)

一个更符合逻辑的例子是:

template<typename T = Foo>
void g(const T & x = T())
{
    // print x, whatever...
}
在无参数调用中,使用
T
的默认
Foo



此外,“
decltype(cT::value_type)
”是无效的
decltype
采用表达式,而不是类型。作者的意思可能是
typename sepT=typename cT::value_type
(需要额外的“
typename
”。

你说的“坏编译器”是什么意思
template<typename T = Foo>
void g(const T & x = T())
{
    // print x, whatever...
}
    g(obj);
    g();    // equivalent to g(Foo());