【问题标题】:error: no matching function for call to 'function namel'错误:没有匹配的函数调用“函数名”
【发布时间】:2018-06-26 00:34:45
【问题描述】:

我的最终目标是计算二次理想的幂,它在 C 中使用 GMP 库实现为结构变量。

我得到了一个库 (ANTL),其中包含使用 C++ 模板、命名空间和 NTL 的通用优化指数。该库对 NTL 类型 ZZ_p 等以及 long、float 等基本类型进行求幂。

我必须使用 ANTL 库来实现我的最终目标 - 计算理想的能力,C 结构变量。因为我之前从未使用过模板和命名空间,所以我想实现一个基本 mpz_t 变量的强大功能,以了解一切是如何工作的。

现在,我有四个头文件 exp.hpp、expbin.hpp、impl.hpp、com.hpp 和一个主文件 exp.cpp,如下 -

COM.HPP

#ifndef GMPL_COM_H
#define GMPL_COM_H

#include <gmp.h>

namespace GMPL {
    template < class T >
    inline void assign(T C, const T A)
    {
        mpz_set(C, A);
    }

    template<class T>
    void mul (T C, const T A, const T B)
    {
        mpz_mul(C, A, B);
    }

    template<class T>
    void sqr (T C, const T A)
    {
        mpz_mul(C, A, A);
    }

}
#endif // guard

EXP.HPP

#ifndef EXP_H
#define EXP_H

#include "com.hpp"

namespace GMPL
{
    template < class T >
    class exp
    {
        public:
        exp() {};
        virtual ~exp() {};

        virtual void power (T C, const T A, const NTL::ZZ & n) = 0;
    };

} // GMPL

#endif // EXP_H

EXPBIN.HPP

#ifndef EXPBIN_H
#define EXPBIN_H

#include "exp.hpp"

namespace GMPL
{
    template < class T >
    class expbin : public exp<T>
    {
        public:
        expbin() {};
        ~expbin() {};

        void power (T C, const T A, const NTL::ZZ & n);
    };

} // GMPL

// Unspecialized template definitions.
#include "impl.hpp"

#endif // EXPBIN_H

IMPL.HPP

using namespace GMPL;

//
// compute A^n using standard left-to-right binary method
//
template < class T > 
void expbin<T>::power (T C, const T A, const NTL::ZZ & n)
{
    assign(C,A);
    for (register long i = NumBits(n)-2 ; i >= 0 ; i--)
    {
        sqr(C, C);
        if (bit(n, i) == 1)
            mul(C, C, A);
    }
}

EXP.CPP

#include <NTL/lzz_p.h>
#include <gmp.h>

namespace GMPL {}
using namespace GMPL;


#include "expbin.hpp"

NTL_CLIENT

int main ()
{
    // NTL variables
    ZZ n;

    // GMP variables
    mpz_t aa;
    mpz_t bb;
    mpz_init(aa);
    mpz_init(bb);

    // generate random exponent of size 512 bits
    RandomLen (n, 512); // NTL function

    // initialize exponentiation classes
    expbin<mpz_t> obj;

    // compute a^n with available methods
    obj.power (bb,aa,n);

    // check and output results
    gmp_printf("%Zd", bb);
}

当我尝试编译 EXP.CPP 时使用(如 Victor Shoup 的在线 NTL 文档中所述)

g++ -g -O2 -std=c++11 -pthread -march=native exp.cpp -o t -lntl -lgmp -lm

我收到以下错误消息-

$ g++ -g -O2 -std=c++11 -pthread -march=native exp.cpp -o t -lntl -lgmp -lm
In file included from exp.cpp:8:
In file included from ./expbin.hpp:46:
./impl.hpp:16:10: warning: 'register' storage class specifier is deprecated and
      incompatible with C++1z [-Wdeprecated-register]
    for (register long i = NumBits(n)-2 ; i >= 0 ; i--)
         ^~~~~~~~~
./impl.hpp:15:5: error: no matching function for call to 'assign'
    assign(C,A);
    ^~~~~~
exp.cpp:28:9: note: in instantiation of member function
      'GMPL::expbin<__mpz_struct [1]>::power' requested here
    obj.power (bb,aa,n);
        ^
./com.hpp:16:17: note: candidate template ignored: deduced conflicting types for
      parameter 'T' ('__mpz_struct *' vs. 'const __mpz_struct *')
    inline void assign(T C, const T A)
                ^
In file included from exp.cpp:8:
In file included from ./expbin.hpp:46:
./impl.hpp:20:13: error: no matching function for call to 'mul'
            mul(C, C, A);
            ^~~
./com.hpp:22:10: note: candidate template ignored: deduced conflicting types for
      parameter 'T' ('__mpz_struct *' vs. 'const __mpz_struct *')
    void mul (T C, const T A, const T B)

对这些错误的刻苦谷歌搜索表明,父类中必须有一个空的构造函数,但我已经有了它。

我知道编译语句是正确的,因为在使用 NTL 时,除此之外没有其他任何作用。在这一点上,我没有解决这个问题的想法。提前致谢。

编辑 这个问题已经解决了。我希望关闭或删除此问题。

【问题讨论】:

    标签: c++ templates compiler-errors gmp ntl


    【解决方案1】:

    一种解决方案是不对函数包装器使用模板。鉴于模板参数必须与mpz_set 兼容,似乎只有一个模板参数有意义(即T 替换为mpz_t)。模板似乎不适合这项工作。只需定义带有mpz_tconst mpz_t 类型参数的包装器:

    inline void assign(mpz_t C, const mpz_t A)
    {
        mpz_set(C, A);
    }
    

    您确实说过您想学习模板,但在不恰当的环境中使用它们并没有太大帮助。而且您仍然拥有可供您的课程学习的模板。

    话虽如此,我可以为您解释编译器消息。


    警告:“注册”存储类说明符已弃用,并且 不兼容 C++1z [-Wdeprecated-register]
    for (register long i = NumBits(n)-2 ; i &gt;= 0 ; i--)

    这是一个很容易解决的问题。摆脱该行中的“注册”。它不再是性能优化。

    错误:没有匹配的函数调用“分配”
    assign(C,A);
    [...]
    注意:候选模板被忽略:推导出的冲突类型 参数'T'

    编译器无法确定在此函数调用中将什么用作模板参数。有两个函数参数,每个参数都暗示assign 的模板参数应该是什么。 (这与expbin 的模板参数不同,尽管两者都命名为T。)当含义发生冲突时,这是一个问题。完成这项工作的一种方法应该是指定您想要的参数,如

    assign<T>(C, A);
    

    这表明assign 的模板参数(在&lt;&gt; 之间给出)应该是expbin 的模板参数(T 在此上下文中的含义)。

    注意:您定义的模板看起来可以正常工作,而无需像这样指定T。然而,mpz_t 在技术上是一个结构的数组(不仅仅是一个结构),用作参数的数组可能会衰减,从而导致类型混淆。

    错误:没有匹配函数调用“mul”
    mul(C, C, A);
    注意:候选模板被忽略:推导出的冲突类型 参数'T'

    相同(尽管在这种情况下有三个函数参数,因此推导出了三个 T 的候选者)。

    mul<T>(C, C, A);
    

    【讨论】:

      猜你喜欢
      • 2013-05-05
      • 2012-12-28
      • 2015-03-31
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 2016-01-18
      相关资源
      最近更新 更多