Riddle – The Shared View

This week I decided to write a riddle, which is consisted of some chosen articles from this blog (and one topic that I didn’t write about yet – std::string_view). This riddle have some parts, so read carefully. The challenge: try to answer without running the code. In your answers, explain the reasons for the answers.

* Link to riddle explanation & solution *

Question #1

  • Does the following code compile?
    • If it compiles, what is the output?
  • Is there a bug in the code?
    • If there is, how can we fix it?
#include <iostream>
#include <memory>
#include <variant>
#include <unordered_map>
#include <string_view>
template<int N> struct fixed_string { 
    constexpr fixed_string(char const (&s)[N]) { 
        std::copy_n(s, N, this->elems);
        elems[N] = 0;
    }
  
    constexpr operator const char*() const { return elems; }
    constexpr operator std::string_view() const { return elems; }
    char elems[N + 1]; 
};
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
template <typename T>
class A {
private:
    template<typename T1>
    using sptr = std::shared_ptr<T1>;
    using p = sptr<T>;
    
public:
    template <typename... Args>
    p create(Args&&... args) {
        return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
    }
    template <typename T1>
    sptr<T1> get(p inst_p, T1* t1) {
        return sptr<T1>(inst_p, t1);
    }
};
struct B {
    using at = std::variant<int*, double*>;
    int a, b;
    double c;
    
    at get(const std::string_view& str) {
        static const std::unordered_map<std::string_view, at> m {
            { "a", &a },
            { "b", &b },
            { "c", &c }
        };
        return m.at(str);
    }
    
private:
    template <fixed_string Str>
    struct get_t {};
    static constexpr const char a_str[] = "a";
    template <>
    struct get_t <a_str> { using type = decltype(a); };
    
    static constexpr const char b_str[] = "b";
    template <>
    struct get_t <b_str> { using type = decltype(b); };
    
    static constexpr const char c_str[] = "c";
    template <>
    struct get_t <c_str> { using type = decltype(c); };
    
public:
    template <fixed_string Str>
    using get_type = typename get_t<Str>::type;
};
class MyAB {
private:
    [[no_unique_address]] A<B> a;
    decltype(a.create()) inst;
    
    auto get(auto& t) { return a.get(inst, &t); }
    
public:
    MyAB() : inst(a.create()) {}
    
    auto get() { return inst; }
    
    template <fixed_string VN>
    auto get_v() {
        std::shared_ptr<B::get_type<VN>> ret;
        std::visit(overloaded {
            [this, &ret](B::get_type<VN>* v) {
                ret = this->get(*v);
            },
            [](auto*) {}
        }, inst->get(VN));
        return ret;
    }
    
    void reset(decltype(inst)::element_type* p) { inst.reset(p); }
};
int main()
{
    MyAB b1, b2;
    auto t1 = b1.get_v<"c">();
    auto t2 = b1.get_v<"a">();
    
    auto t3 = b2.get_v<"a">();
    auto t4 = b2.get_v<"c">();
    
    *t1 = 1.2;
    *t2 = 3;
    
    *t3 = 4;
    *t4 = 5.6;
    std::cout << *t1 << *t2 << *t3 << *t4 << "\n";
    /* (1)
    b1.reset(nullptr);
    t1.reset();
    t2.reset();
    std::cout << *t3 << *t4;
    */
    /* (2) 
    b1.reset(b2.get().get());
    std::cout << *t1 << *t2 << *t3 << *t4 << "\n";
    */
    return 0;
}

Question #2 – comment (1)

How does the commented section will effect the (original) code, what will be the result, and why?

Question #3 – comment (2)

How does the commented section will effect the (original) code, what will be the result, and why?

The Answers

The answers to this riddle will be published in the next article, alongside the name of the first person who will give the correct answer in this article’s comments section. Good Luck!

One thought on “Riddle – The Shared View

Leave a comment