【发布时间】:2021-11-09 02:21:11
【问题描述】:
我有一个模板类,我在其中重载了加法和输出运算符,并且我有一个特定的专业化也是模板化的。我还没有找到任何关于如何执行此操作的示例,并且最终出现链接错误,所以我想知道它是否可能。
// Point.hpp
namespace crypto {
// Forward declarations for template specialization
template<class T> class FieldElement;
template<class T> class Point;
template<class T> std::ostream& operator<<(std::ostream& out, const Point<T>& point);
template<class T> std::ostream& operator<<(std::ostream& out, const Point<FieldElement<T>>& point);
template<class T> Point<T> operator+(const Point<T>& lhs, const Point<T>& rhs);
template<class T>
Point<FieldElement<T>> operator+(const Point<FieldElement<T>>& lhs, const Point<FieldElement<T>>& rhs);
template<class T> class Point
{
public:
Point(std::optional<T> x, std::optional<T> y, T a, T b);
~Point() = default;
template<class U> friend Point operator+(const Point& lhs, const Point& rhs);
template<class U> friend std::ostream& operator<<(std::ostream& os, const Point<U>& element);
std::optional<T> X;
std::optional<T> Y;
T A;
T B;
};
template<class T> Point<T> operator+(const Point<T>& lhs, const Point<T>& rhs)
{
...
}
template<class T> std::ostream& operator<<(std::ostream& os, const Point<T>& point)
{
// Write Point to stream
if (!point.X)
os << "Point(infinity)";
else
os << "Point(" << point.X.value() << "," << point.Y.value() << ")_" << point.A << "_" << point.B;
return os;
}
}
还有专业:
// Point.cpp
namespace crypto {
template<class T> Point<FieldElement<T>> operator+(const Point<FieldElement<T>>& lhs, const Point<FieldElement<T>>& rhs)
{
...
}
template<class T> std::ostream& operator<<(std::ostream& os, const Point<FieldElement<T>>& point)
{
if (!point.X)
os << "Point(infinity)";
else
{
os << "Point(" << point.X.value().Number << "," << point.Y.value().Number << ")_" << point.A.Number << "_"
<< point.B.Number << " FieldElement(" << point.X.value().Prime << ")";
}
return os;
}
}
调用代码:
// Test.cpp
TEST(IntegrationTests, PointAdditionTests)
{
auto prime = 223;
auto a = FieldElement(0, prime);
auto b = FieldElement(7, prime);
auto x1 = FieldElement(192, prime);
auto y1 = FieldElement(105, prime);
auto x2 = FieldElement(17, prime);
auto y2 = FieldElement(56, prime);
auto p1 = Point<FieldElement<int>>(x1, y1, a, b);
auto p2 = Point<FieldElement<int>>(x2, y2, a, b);
std::cout << p1 + p2 << std::endl;
}
最后是我的链接错误: clang++ -o 构建
d/bitcoin/crypto/CryptoLibTests -pthread build/bitcoin/crypto/tests/CryptoIntegrationTests.o build/bitcoin/crypto/tests/FieldElementTests.o build/bitcoin/crypto/tests/PointTests.o -Lbuild/lib -lpthread -lBtcCrypto -lgtest -lgtest_main
Undefined symbols for architecture x86_64:
"std::__1::basic_ostream<char, std::__1::char_traits<char> >& crypto::operator<<<int>(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, crypto::Point<crypto::FieldElement<int> > const&)", referenced from:
IntegrationTests_PointAdditionTests_Test::TestBody() in CryptoIntegrationTests.o
"crypto::Point<crypto::FieldElement<int> > crypto::operator+<int>(crypto::Point<crypto::FieldElement<int> > const&, crypto::Point<crypto::FieldElement<int> > const&)", referenced from:
IntegrationTests_PointAdditionTests_Test::TestBody() in CryptoIntegrationTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
scons: *** [build/bitcoin/crypto/CryptoLibTests] Error 1
scons: building terminated because of errors.
【问题讨论】:
-
专业化仅在 Point.cpp 中可用。见Why can templates only be implemented in the header file?
-
嗯,你知道吗,这行得通!谢谢你,@paddy
标签: c++ templates operator-overloading