Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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/3/templates/2.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_C++11 - Fatal编程技术网

C++ 如何使用调用模板化类型

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

我试图创建一个模板函数,该函数基于一个模板参数有两个不同的实现。第一种是针对I/O操纵器的,第二种是针对任何一般情况的

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 la
auto p=&foo;
的指针的代码,它忽略了重载;但这通常不是一个实际问题。非常感谢。但是我必须使用foohelper,这就是我写申请书的方式。