C++ 如何使用调用模板化类型
我试图创建一个模板函数,该函数基于一个模板参数有两个不同的实现。第一种是针对I/O操纵器的,第二种是针对任何一般情况的C++ 如何使用调用模板化类型,c++,templates,c++11,C++,Templates,C++11,我试图创建一个模板函数,该函数基于一个模板参数有两个不同的实现。第一种是针对I/O操纵器的,第二种是针对任何一般情况的 template <typename T> typename std::enable_if< std::is_same<decltype(std::setw), T>::value>::type foo(T& t){ cout << "enabled" << std::e
template <typename T>
typename std::enable_if<
std::is_same<decltype(std::setw), T>::value>::type
foo(T& t){
cout << "enabled" << std::endl;
}
template <typename T>
void foo(T& t){
cout << "Normal" << std::endl;
}
template <typename... Ts>
void foohelper(Ts... t){
foo(t...);
}
int main(){
foohelper(std::setprecision(3)); // It should print enabled, but printing Normal
}
模板
typename std::启用\u如果<
std::is_same::value>::类型
傅(T&T){
cout这些函数的返回类型未指定。这意味着您不能使用type\u traits
来比较它们。例如,libcxx
:
// Definitions omitted
T2 setiosflags (ios_base::fmtflags mask);
T3 setbase(int base);
template<charT> T4 setfill(charT c);
T5 setprecision(int n);
T6 setw(int n);
//省略了定义
T2 setiosglags(ios_base::fmtflags掩码);
T3退变基(int-base);
模板T4设置填充(图c);
T5设定精度(整数n);
T6 setw(int n);
T5
,T6
等。参考\uu imo\u t4
等,一种执行操纵器实际工作的内部结构。由于它们都有不同的返回类型,因此函数有不同的类型。因此它们都会有所不同。您不需要使用启用\u if
-只需专门化下面的模板即可e模板foo的主要定义
template <>
void foo<decltype(std::setw(0))>(decltype(std::setw(0))& t)
{
cout << "enabled" << std::endl;
}
模板
void foo(decltype(std::setw(0))和t)
{
cout您可以通过比较函数std::setprecision
的返回类型来使用SFINAE。由于返回类型未指定,因此需要decltype
和std::declval
以下是解决方案:
template <typename T, typename std::enable_if<std::is_same<decltype(std::setprecision(std::declval<int>())), typename std::decay<T>::type>::value, int>::type = 0>
void foo(T&& t) {
cout << "enabled" << std::endl;
}
模板
无效foo(T&T){
你可以使用未指定的类型吗?一个很好的例子是std::bind
@GuillaumeRacicot的返回类型std::bind
与比较std::setw
和std::setprecision
有什么关系?这些函数的类型是未指定的,您不能将它们与type_traits一起使用来比较它们。这不是真的,std::bind
和lambda都有未指定的类型,我通常在类型traits和模板参数中使用它们。我甚至通过调用它们的operaor()来使用这些类型
。声明不能在类型特征中使用它们,因为它们的类型未指定是不正确的。@GuillaumeRacicot:lambda和未指定的返回类型std::bind
应该有一些接口作为操作符()
,使用未指定的类型作为特征会导致未指定的特征。T2
和T3
可能是相同的类型或不相同的类型,因此对其中一个的专门化也可能适用于另一个,并且专门化两者可能编译或不编译。std::set和std::setprecision不是相同的类型(也是std::setprecision(3)与std::setprecision的类型不同)也许如果你对这个问题进行更详细的阐述,我们可以给你一个答案!是的,我的意思是std::setw。它们实际上是不同的,请看这里的源代码,它们返回一个结构,但每个结构都有不同的名称!试着验证std::cout谢谢它的工作,不是吗?我不明白为什么我必须将定义保留在main下面?看起来不错,但是在这种情况下,t是专门化可以用简单的重载来代替吗?@AAA:我的措辞很糟糕-不是在函数main()
下面,而是在模板的主要定义下面,即template void foo(t&t)下面…
。模板应该在专业化之前查看。@GuillaumeRacicot:对于这个特定的调用,是的,但是假设函数模板f
包含获取指向函数a laauto p=&foo;
的指针的代码,它忽略了重载;但这通常不是一个实际问题。非常感谢。但是我必须使用foohelper,这就是我写申请书的方式。