我的最终目标是计算使用GMP库在C中作为结构变量实现的二次理想的幂。
已为我提供了一个库(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)
对这些错误的刻苦搜寻表明,在父类中必须有一个空的构造函数,但是我已经有了。
我知道compile语句是正确的,因为在使用NTL时,除此之外没有其他作用。在这一点上,我没有办法解决这个问题。预先感谢。
编辑 这个问题已经解决。我希望这个问题能够解决或取消。
答案 0 :(得分:0)
一种解决方案是不为函数包装使用模板。假设模板参数必须与T
兼容,似乎只有一个有意义的模板参数(即mpz_t
被mpz_set
取代)。模板似乎是完成这项工作的错误工具。只需使用mpz_t
和const 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 >= 0 ; i--)
这是一个容易解决的问题。摆脱该行中的“注册”。不再是性能优化。
错误:没有匹配的函数可调用'assign'
assign(C,A);
[...]
注意:候选模板被忽略:推导冲突类型为 参数“ T”
编译器在弄清楚该函数调用中用作模板参数时遇到麻烦。有两个函数参数,每个参数都隐含assign
的模板参数。 (这与expbin
的模板参数是不同的,尽管两者都被命名为T
。)当含义冲突时,这是一个问题。进行这项工作的一种方法应该是指定所需的参数,例如
assign<T>(C, A);
这明确表明assign
的模板参数(在<
和>
之间)应该是expbin
的模板参数({ {1}})。
注意:您定义的模板看起来通常可以正常工作,而无需指定T
。但是,T
从技术上讲是一个结构的数组(不仅仅是一个结构),用作自变量的数组可能会衰减,从而导致类型混淆。
错误:没有匹配的函数可以调用'mul'
mpz_t
注意:候选模板被忽略:推导冲突类型为 参数“ T”
相同(尽管在这种情况下有三个函数参数,所以推导了mul(C, C, A);
的三个候选者)。
T