【问题标题】:Passing Function Type As Template Parameter Does Not Compile将函数类型作为模板参数传递不会编译
【发布时间】:2019-12-09 03:27:00
【问题描述】:

所以我有一个类,它接受两个模板参数,一个是类型,一个是使用的函数的类型,它有一个reduce 函数,可以将该函数重复应用于数组。但是,我遇到了编译错误。

function_template_test.cpp: In instantiation of 'class _C<int, int(int, int)>':
function_template_test.cpp:36:33:   required from here
function_template_test.cpp:11:17: error: field '_C<int, int(int, int)>::op' invalidly declared function type
  BinaryOperator op;

这是我的代码。我在 main 方法下面有一个类和驱动程序代码。

#include<iostream>
template<typename _T>
_T addition(_T x,_T y)
{
    return x+y;
}
template<typename _T,typename BinaryOperator>
class _C
{
private:
    BinaryOperator op;
public:
    _C(BinaryOperator op)
    {
        this->op=op;
    }
    _T reduce(_T*begin,_T*end)
    {
        _T _t_=*begin;
        ++begin;
        while(begin!=end)
        {
            _t_=this->op(_t_,*begin);
            ++begin;
        }
        return _t_;
    }
    _T operator()(_T*begin,_T*end)
    {
        return this->reduce(begin,end);
    }
};
int main(int argl,char**argv)
{
    int arr[]={1,4,5,2,9,3,6,8,7};
    _C<int,decltype(addition<int>)>_c_=_C<int,decltype(addition<int>)>(addition<int>);
    std::cout<<_c_(arr,arr+9)<<std::endl;
    return 0;
}

【问题讨论】:

    标签: c++ function templates


    【解决方案1】:

    您将函数类型指定为BinaryOperator 的模板参数,它不能用作数据成员op 的类型;您可以改为指定 函数指针类型。例如

    _C<int,decltype(addition<int>)*>_c_=_C<int,decltype(addition<int>)*>(addition<int>);
    //                            ^                                   ^
    

    顺便说一句:像 _C 这样以下划线开头的名称在 C++ 中是 reserved

    【讨论】:

    • 另外我注意到标准库中很多东西前面都有下划线,所以我开始使用它们,我不知道它们是保留的。
    • @DSOI__UNUNOCTIUM 是的,它们是为库保留的,以避免库实现与您自己的实现发生冲突。
    【解决方案2】:

    通常在将函数分配给函数指针时,您不需要显式添加运算符的地址 (&amp;),因为将函数本身分配给变量是无效的,因此语言会自动为您添加它.但是,在对函数名称执行 decltype 时,您确实会得到函数类型而不是函数指针。例如尝试编译以下内容,所有static_asserts 都应该通过:

    #include <type_traits>
    
    void foo() {}
    
    int main()
    {
        auto a = foo;
        auto b = &foo;
        static_assert(std::is_same_v<decltype(a), decltype(b)>,"a and b are function pointers");
        static_assert(!std::is_same_v<decltype(a), decltype(foo)>,"foo is not a function pointer");    
        static_assert(std::is_same_v<decltype(a), decltype(&foo)>,"&foo is a function pointer");    
    }
    

    您的代码基本上等同于:

    #include <type_traits>
    
    void foo() {}
    
    int main()
    {
        decltype(foo) c = foo;
    }
    

    无法编译。将其更改为此可以解决问题:

    #include <type_traits>
    
    void foo() {}
    
    int main()
    {
        decltype(&foo) c = foo;
    }
    

    您的代码的修复方法是将其更改为:

    _C<int,decltype(&addition<int>)>_c_=_C<int,decltype(&addition<int>)>(addition<int>);
    

    或者你可以通过直接构造来避免重复类型:

    _C<int,decltype(&addition<int>)>_c_(addition<int>);
    

    或者使用auto:

    auto _c_=_C<int,decltype(&addition<int>)>(addition<int>);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-29
      • 2019-04-24
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多