c++ - 外参数包可以用内参数包展开推导吗?

标签 c++ templates c++11 language-lawyer variadic-templates

给定重载函数 f1 :

void f1(int);
int f1(char);

还有一个类模板X带成员(member)模板f :

template<class T>
struct X
{
    template<class U>
    static void f(T(*p)(U));
};

编译器能够解析f1来自部分函数类型:

X<int>::f(f1); // T = int (specified), U = char (deduced)
X<void>::f(f1); // T = void (specified), U = int (deduced)

但是,可变类模板 Y两侧都有参数包:

template<class... T>
struct Y
{
    template<class... U>
    static void f(T(*...p)(U));
};

做同样的事情失败:

Y<int>::f(f1); // error
Y<void>::f(f1); // error
Y<int, void>::f(f1, f1); // error

注意,如果参数包只在一侧是可以的:

template<class... T>
struct Z1
{
    template<class U>
    static void f(T(*...p)(U));
};

template<class T>
struct Z2
{
    template<class... U>
    static void f(T(*...p)(U));
};

Z1<int>::f(f1); // ok
Z2<void>::f(f1); // ok

这说明了一个问题:外参数包T内部参数包无法扩展 U仍然依赖。 我想编译器可以扩展 Y::fY<int, void> 时到类似下面的内容被实例化:

template<class... U>
void f(int(*p0)(U0), void(*p1)(U1));

哪里U0U1表示参数包的前 2 个元素 U .

但似乎编译器(g++/clang)拒绝这样做并留下整个p未用完。 它在标准中的哪个位置指定了这种行为?它可能是标准缺陷还是需要改进?

最佳答案

我已经提取了另一个有效的代码片段,虽然仍然不能满足您的需求,但可能会引导您做一些事情:

void f1(int)
{

}

int f1(char)
{
    return 0;
}

template <class Out, class In>
struct UniFunction
{
    typedef Out fn(In);
    typedef fn* ptr;
};

template<class... T>
struct Y
{
  //template<class... U>
  //static void f(T(*...p)(U)...);
    template <class... U>
    struct YY
    {
        static void f(typename UniFunction<T, U>::ptr...)
        {

        }
    };


};

int main( int argc, char** argv )
{

    Y<int>::YY<char>::f(f1);

    return 0;
}

UniFunction只是为了清楚起见,也许表明参数包的双重并行扩展并非不可能,只是有一个小问题。

我认为如果您另外提供一个“模板函数”(带有 typedef 的结构模板),它将从函数指针中提取(使用 type_traits 或其他东西)参数类型和返回类型,您仍然可以强制执行参数类型推导。这样,您应该能够提供 Y::f只有一个模板参数(有点 X... )的函数,从 X 中提取参数类型作为函数指针,然后将其显式传递给 YY模板,如此处所示。

关于c++ - 外参数包可以用内参数包展开推导吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39283666/

相关文章:

c++ - 如何在隐藏/显示时保持 QDialog 的位置

C++ 静态库

c++ - 进程终止,状态为 -1073741571(0 分钟,3 秒)

c++ - C++0x中的统一初始化,什么时候用()代替{}?

c++ - 移出的 xvalue 究竟需要什么?

c++ - 使用 -1 初始化结构或数组的无符号 {} 初始化

c++ - C++ 中的数组指针

c++ - 美化变量模板化函数调用

c++ - 使用 -Wl,--as-needed 强制与共享库链接(仅提供模板时)

c++ - 如何处理在 C++ 中已知模板参数数量的虚拟模板函数?