【问题标题】:Templated class operator overload specialization with templated argument [duplicate]具有模板化参数的模板化类运算符重载特化 [重复]
【发布时间】: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.

【问题讨论】:

标签: c++ templates operator-overloading


【解决方案1】:

感谢@paddy,答案是将专业化移动到头文件中。然后上面的实现就可以了

【讨论】:

    猜你喜欢
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 2018-12-30
    • 1970-01-01
    相关资源
    最近更新 更多