Take the tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am designing a class which (among other things) acts as a vertex in an undirected graph.

#include <iterator>
#include <string>

class Node
{
public:
    explicit Node(const std::string& name);
    Node(const Node&);
    Node(Node&&);

    class iterator
        : public std::iterator<std::random_access_iterator_tag, const Node>
    {
        //...
    };
    class container_proxy
    {
    public:
        iterator begin() const;
        iterator end() const;
    private:
        //...
    };

    container_proxy neighbors() const;

    add_link(Node& other);

    //...

private:
    //...
};
// to support: for (const Node& neighbor : node.neighbors())
Node::iterator begin(const Node::container_proxy&);
Node::iterator end(const Node::container_proxy&);

Now I want to define a function link_complete which:

  • takes any number of arguments
  • allows non-const Node lvalues (parameter type Node&)
  • allows non-const Node rvalues (parameter type Node&&)
  • does not allow any other parameter type.

An example usage:

Node ret_by_value();

void example_test(Node& x, Node&& y)
{
    link_complete(x, ret_by_value(), std::move(y), Node("test"));
}

Here's the solution I came up with:

#include <initializer_list>
#include <type_traits>

class Node {
    //...
public:
    static void link_complete(std::initializer_list<Node*> node_list);
};

template <typename ... Types>
struct template_all; // UNDEFINED

template <>
struct template_all<>
  : public std::true_type {};

template <typename ... Types>
struct template_all<std::false_type, Types...>
  : public std::false_type {};

template <typename ... Types>
struct template_all<std::true_type, Types...>
  : public template_all<Types...>::type {};

template <typename ... Args>
auto link_complete(Args&& ... args) ->
  typename std::enable_if<
    template_all<
      typename std::is_same<
        typename std::remove_reference<Args>::type,
        Node
      >::type ...
    >::value,
    void
  >::type
{
    Node::link_complete( { &args... } );
}

It seems to work as required, but I'm wondering if there was a simpler or "prettier" way to do it, or maybe a way to improve that template_all helper type. All C++11, tr1, and boost features are welcome. I did notice boost::mpl::and_ looks similar to my template_all helper type, but Boost MPL seems like a tricky learning curve and/or overkill for this problem.

share|improve this question
add comment

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.