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_Function Templates_Template Templates - Fatal编程技术网

C++ 计算为单个参数的模板模板参数

C++ 计算为单个参数的模板模板参数,c++,templates,function-templates,template-templates,C++,Templates,Function Templates,Template Templates,在下面的代码中,类模板使用一个参数,但如果模板参数是模板,则函数模板使用两个参数。这在使用类型推断时是正常的,但在使用显式模板实例化时是不正常的 是否可以将模板参数作为单个参数写入 这个问题与 #包括 模板 结构C { C(T i) { 标准::可与SFINAE: #include <type_traits> template<class T> struct is_template_with_one_param : std::false_type {}; templa

在下面的代码中,类模板使用一个参数,但如果模板参数是模板,则函数模板使用两个参数。这在使用类型推断时是正常的,但在使用显式模板实例化时是不正常的

是否可以将模板参数作为单个参数写入

这个问题与

#包括
模板
结构C
{
C(T i)
{
标准::可与SFINAE:

#include <type_traits>

template<class T>
struct is_template_with_one_param
: std::false_type
{};

template<template<class> class TT, class T>
struct is_template_with_one_param< TT<T> >
: std::true_type
{};


#include <iostream>

template <typename T>
typename std::enable_if< not is_template_with_one_param<T>{}, void >::type
F (T i)
{
    std::cout << "simple" << std::endl;
}

template <typename T>
typename std::enable_if< is_template_with_one_param<T>{}, void >::type
F (T i)
{
    std::cout << "template" << std::endl;
}
#包括
模板
结构是带有一个参数的模板
:std::false\u类型
{};
模板
结构是带有一个参数的模板
:std::true\u类型
{};
#包括
模板
typename std::enable_if::type
F(ti)
{

std::cout另一种可能的解决方案:

#include <iostream>

template <typename T>
struct C
{
    C (T i)
    {
        std::cout << "simple" << std::endl;
    }
};
template <template<typename TT> class FF, typename TT>
struct C <FF<TT> >          // (1)
{
    C (FF<TT> i)
    {
        std::cout << "template" << std::endl;
    }
};

template <typename T>
void F (T i)
{
    C<T> x(i);
}

template <typename T>
struct R
{
    T x;
};
int main()
{
        R<int>     r;
        F(r);
        F(4);
}
#包括
模板
结构C
{
C(T i)
{

std::我很惭愧地承认,但我从来都不了解模板参数。最终我放弃了尝试。这归结为这样一个事实:因为函数模板不支持部分专门化,所以在函数模板的情况下,您喜欢的类模板的模式匹配是不存在的。我认为这是可能的使用SFINAE;这两个函数将采用相同的参数,但一个接受非模板类型,而另一个接受模板专门化。经典的方法是将函数转发到结构实现(即:
template void F(T){C()(T);}
使用
operator()
而不是构造函数)。作为一种算法,重载解析在这里的工作方式没有什么不同,但其输入数据在这两种情况下是不同的。对于明确指定的
F(R)
,重载集(=使用名称
F
找到的函数,已经对其执行了类型推断和替换)是
void F(R);
(即函数
void F(R)
带有
T=R
)和
void F(R);
(函数
void F(T)
带有
T=R
)。注意,您没有指定参数类型,而是指定模板参数;因此第一个函数成为
F(R)
.N.B.其中一个重载也可以写为
模板void F(ti,TT…)
这是一个正确的答案。但这是一个解决办法,所以我将等待一段时间,然后再将其标记为正确答案。我想知道是否有一个自然的“一个参数”语法。但恐怕没有。这就是为什么每个人都使用带有静态函数的类模板作为变通方法,这实际上比使用SFINAE更好。@PatrickFromberg,正如Nawaz所说,另一种方法是显式专门化,如
模板void F(R)函数模板的部分专门化是不允许的;如果允许的话,可以编写
模板void F(TT);
。如问题中所述,类型推断工作正常。问题出现的地方是显式实例化。@Patrick Fromberg:
F(r)
F(4)
也可以工作。
#include <type_traits>

template<class T>
struct is_template_with_one_param
: std::false_type
{};

template<template<class> class TT, class T>
struct is_template_with_one_param< TT<T> >
: std::true_type
{};


#include <iostream>

template <typename T>
typename std::enable_if< not is_template_with_one_param<T>{}, void >::type
F (T i)
{
    std::cout << "simple" << std::endl;
}

template <typename T>
typename std::enable_if< is_template_with_one_param<T>{}, void >::type
F (T i)
{
    std::cout << "template" << std::endl;
}
template <typename T>
struct R
{
    T x;
};
int main()
{
        F(R<int>{});
        F(42);
}
#include <iostream>

template <typename T>
struct C
{
    C (T i)
    {
        std::cout << "simple" << std::endl;
    }
};
template <template<typename TT> class FF, typename TT>
struct C <FF<TT> >          // (1)
{
    C (FF<TT> i)
    {
        std::cout << "template" << std::endl;
    }
};

template <typename T>
void F (T i)
{
    C<T> x(i);
}

template <typename T>
struct R
{
    T x;
};
int main()
{
        R<int>     r;
        F(r);
        F(4);
}