运算符>>未定义为什么?

时间:2019-10-29 11:39:10

标签: c++ operator-overloading

我正在尝试帮助this question,并且我认为我找到了一个不错的解决方案。但这有点复杂,因为我需要所有包装。 我想重载operator>>以允许使用简单的链接表示法。但是它没有按我预期的那样工作。

我可以做到:

#include <functional>
#include <memory>

template<typename T>
class Object {
private:
    T* const ptr{ nullptr };
public:
    Object(T* ptr) noexcept : ptr(ptr) {}
    T* Get() const noexcept { return ptr; }
};

using MyObject = Object<int>;

template <typename T, typename MemFn>
auto fnc (T* ptr, MemFn memFn)
-> decltype(std::invoke(memFn, std::declval<T>())) {
    if (ptr) return std::invoke(memFn, *ptr);
    return nullptr;
}

int main() {
    std::unique_ptr<MyObject> myObjectPtr = std::make_unique<MyObject>(nullptr);
    [[maybe_unused]] int* optionalTarget = fnc(myObjectPtr.get(), &MyObject::Get);
}

但是,我想做

#include <functional>
#include <memory>

template<typename T>
class Object {
private:
    T* const ptr{ nullptr };
public:
    Object(T* ptr) noexcept : ptr(ptr) {}
    T* Get() const noexcept { return ptr; }
};

using MyObject = Object<int>;

template <typename T, typename MemFn>
auto operator>> (T* ptr, MemFn memFn)
-> decltype(std::invoke(memFn, std::declval<T>())) {
    if (ptr) return std::invoke(memFn, *ptr);
    return nullptr;
}

int main() {
    std::unique_ptr<MyObject> myObjectPtr = std::make_unique<MyObject>(nullptr);
    [[maybe_unused]] int* optionalTarget = myObjectPtr.get() >> &MyObject::Get;
}

什么是行得通的,但我认为丑陋的是

#include <functional>
#include <memory>
#include <optional>

template<typename T>
class Object {
private:
    T* const ptr{ nullptr };
public:
    Object(T* ptr) noexcept : ptr(ptr) {}
    T* Get() const noexcept { return ptr; }
};

using MyObject = Object<int>;

template <typename T>
auto makeOptRef(T* ptr) -> std::optional< std::reference_wrapper<T>> {
    if (ptr) return std::ref(*ptr);
    return {};
}

template <typename T, typename MemFn>
auto operator>> (std::optional<std::reference_wrapper <T>> ptr, MemFn memFn)
-> std::optional<std::reference_wrapper<std::remove_pointer_t<decltype(std::invoke(memFn, std::declval<T>()))>>> {
    if (ptr) return makeOptRef(std::invoke(memFn, *ptr));
    return {};
}

int main() {
    std::unique_ptr<MyObject> myObjectPtr = std::make_unique<MyObject>(nullptr);
    std::optional<std::reference_wrapper<MyObject>> myObjOptRef = makeOptRef(myObjectPtr.get());

    std::optional<std::reference_wrapper<int>> optionalTarget = myObjOptRef >> &MyObject::Get;

    [[maybe_unused]] int output = (optionalTarget) ? optionalTarget->get() : -1;
}

1 个答案:

答案 0 :(得分:8)

任何指针类型都是内置类型,指向成员的指针也是如此。您正在尝试为两个内置类型重载运算符,这简直是不可启动的。至少一个参数必须是用户定义的类型或对其的引用。

您可以通过传递T&而不是T*来使其正常工作。