C++ std::endl和可变模板

C++ std::endl和可变模板,c++,c++11,variadic-templates,C++,C++11,Variadic Templates,代码: #包括 作废 { } 模板 作废(T值,参数…参数) { std::coutstd::endl是一个重载函数(在许多STL实现中,它是一个模板),编译器没有关于选择内容的信息 只需将其转换为static\u cast(std::endl)事实上,这是一个模板,而不是重载。@jogojapan:从技术上讲,模板是一个“重载生成器”:与流类一样多的std::endl。这是否是通过声明其中一些类(例如ostream和wostream)来实现的或模板(在ostream上)是一个实现细节,它不会改

代码:

#包括
作废
{
}
模板
作废(T值,参数…参数)
{

std::cout
std::endl
是一个重载函数(在许多STL实现中,它是一个模板),编译器没有关于选择内容的信息


只需将其转换为
static\u cast(std::endl)

事实上,这是一个模板,而不是重载。@jogojapan:从技术上讲,模板是一个“重载生成器”:与流类一样多的
std::endl
。这是否是通过声明其中一些类(例如ostream和wostream)来实现的或模板(在
ostream
上)是一个实现细节,它不会改变选择重载的方式。对于解决方案的有效性来说,这没有什么区别,但模板实例化和重载解析是两种截然不同的机制。将模板称为重载生成器是一种误导。按照您描述的方式,模板生成s一组函数,然后应用重载解析来选择一个。这是不正确的,原因有两个:a)在简单重载解析的情况下,要从中选择的函数集是预定义的,而隐式类型转换是编译器可以用来查找给定参数与所选函数之间匹配的唯一机制,而在模板实例化的情况下,可以生成一个新的函数实例来精确匹配给定的参数。这在不明确的情况下具有广泛的含义。b)如果std::endl是一组重载,则库实现有一个错误,因为它与自定义字符特征不可用(或自定义字符类型)
out(&std::endl);
#include <iostream>

void out()
{
}

template<typename T, typename... Args>
void out(T value, Args... args)
{
    std::cout << value;
    out(args...);
}

int main()
{
    out("12345", "  ", 5, "\n"); // OK
    out(std::endl);              // compilation error
    return 0;
}
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -pthread -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
../main.cpp: In function ‘int main()’:
../main.cpp:17:15: error: no matching function for call to ‘out(<unresolved overloaded function type>)’
../main.cpp:17:15: note: candidates are:
../main.cpp:3:6: note: void out()
../main.cpp:3:6: note:   candidate expects 0 arguments, 1 provided
../main.cpp:8:6: note: template<class T, class ... Args> void out(T, Args ...)
../main.cpp:8:6: note:   template argument deduction/substitution failed:
../main.cpp:17:15: note:   couldn't deduce template parameter ‘T’