【问题标题】:Passing a function that accepts any number and type of arguments as a class template argument传递一个接受任意数量和类型的参数作为类模板参数的函数
【发布时间】:2018-09-04 10:20:00
【问题描述】:

我知道函数可以是模板参数。但是 GCC、Clang 和 MSVC(编译版本在rextester)在模板为可变参数时不编译编译,如下所示:

void Func( int ){}

template<void (*)(int)>
struct Foo{};

template struct Foo<Func>; // Compiles

template<typename>
struct Bar;

template<typename ...Args>
struct Bar<void(*)(Args...)>
{
};

template struct Bar<Func>; // Does NOT compile (why???)

int main()
{
}

MSVC 产生最详细的输出和可能的解释(正确或错误),说明代码为何无法编译。

source_file.cpp(20): error C2923: 'Bar': 'Func' is not a valid template type argument for parameter 'T'
source_file.cpp(1): note: see declaration of 'Func'
source_file.cpp(20): error C2990: 'Bar': non-class template has already been declared as a class template
source_file.cpp(13): note: see declaration of 'Bar'
source_file.cpp(20): error C2946: explicit instantiation; 'Bar' is not a template-class specialization  

什么是传递函数的适当语法,这些函数本身接受任意数量的参数作为类模板参数。

【问题讨论】:

    标签: c++ variadic-templates


    【解决方案1】:

    Func 不是类型,而是函数,

    你可能想要:

    template struct Bar<decltype(&Func)>;
    

    或许

    template<typename F, F f> struct Bar;
    
    template <typename ...Args, void(*f)(Args...)>
    struct Bar<void(*)(Args...), f>
    {
    };
    

    Bar&lt;decltype(&amp;Func), &amp;Func&gt;

    可以简化为(C++17 起):

    template <auto> struct Bar;
    
    template <typename ...Args, void(*f)(Args...)>
    struct Bar<f>
    {
    };
    

    Bar&lt;&amp;Func&gt;

    【讨论】:

    • 那是我最初的解决方案。我只是想知道为什么template struct Foo&lt;Func&gt;; 编译。
    • @Olumide 因为Foo 采用非类型参数(void (*)(int) 类型)
    • @user463035818 谢谢。顺便说一句,我什至不认为我的 Bar 专业与 template struct Bar&lt;decltype(&amp;Func)&gt; 匹配,至少在 GCC 和 Clang 上不匹配,因为他们抱怨 template 'Bar&lt;decltype(Func)&gt; 未定义。
    • @Jarod42 你用的是哪个编译器。更新后的答案的 C++17 和 C++17 版本无法在 GCC 7.3.0 上编译。
    • @Olumide:使用 clang 版本 5.0.0-3~16.04.1 和 g++ (GCC) 8.1.0 编译 here
    猜你喜欢
    • 2021-03-29
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 2011-04-15
    相关资源
    最近更新 更多