diff --git a/libwccl/variables.h b/libwccl/variables.h
index 902cf1e10f0dedcdbb61da7b850b8eba8afd7d9e..107d36b2521dfef0be71f4cc5fd1c59df00a8d95 100644
--- a/libwccl/variables.h
+++ b/libwccl/variables.h
@@ -63,6 +63,70 @@ public:
 	std::string varname;
 };
 
+/**
+ * Exception class for invalid variable name errors in situations where
+ * it is not possible to return a NULL-equivalent
+ */
+class InvalidVariableName : public WcclError
+{
+public:
+	InvalidVariableName(const std::string& varname)
+	 : WcclError("Invalid variable name"), varname(varname)
+	{}
+
+	~InvalidVariableName() throw() {}
+
+	std::string varname;
+};
+
+/**
+ * Base class for the "fast" variable accesors.
+ */
+class BaseAccesor
+{
+public:
+	/// Variable name getter
+	const std::string get_name() const {
+		return varname_;
+	}
+protected:
+	/// Protected ctor, only constructed by derived classes
+	BaseAccesor(const std::string& varname)
+		: varname_(varname)
+	{
+	}
+
+	std::string varname_;
+};
+
+/**
+ * A "fast" accesor class for getting a variable off a Variables object.
+ *
+ * It should be faster to create an accesor object from the variables name and
+ * then use it multiple times than to use the name itself often.
+ *
+ * @todo the above is not the case yet.
+ *
+ * Objects of the accesor class can only be created by the Variables object,
+ * are valid only for that Variables object and might stop working if the
+ * Variables object is touched in the wrong way in between the creation and use
+ * of a VariableAccesor. UB is meant by "stop working".
+ */
+template<typename T>
+class VariableAccesor : public BaseAccesor
+{
+public:
+
+protected:
+	/// Protected ctor, only created by Variables::create_accesor
+	VariableAccesor(const std::string& varname)
+		: BaseAccesor(varname)
+	{
+	}
+
+	friend class Variables;
+};
+
 /**
  * A class for holding variables.
  *
@@ -124,6 +188,44 @@ public:
 		return detail::Vmap<T>::get(s);
 	}
 
+	/** Create a "fast" accesor for a variable by name.
+	 *
+	 * Returns a special object which is valid for use in get_fast, which when
+	 * used should be faster than calling get<T>(s) repeatedly.
+	 *
+	 * If the variable name is invalid or teh type doesn't match, an exception
+	 * will be thrown, either VariableTypeMismatch or InvalidVariableName.
+	 */
+	template<typename T>
+	VariableAccesor<T> create_accesor(const std::string& s) {
+		BOOST_MPL_ASSERT(( boost::mpl::count<types, T> ));
+		if (!get<T>(s)) {
+			if (get<Value>(s)) {
+				throw VariableTypeMismatch(s);
+			} else {
+				throw InvalidVariableName(s);
+			}
+		}
+		return VariableAccesor<T>(s);
+	}
+
+	/** Get a variable using a "fast" accesor.
+	 *
+	 * The accesor is required to have been created by this particular object,
+	 * and the Variables object must have not had variables removed, however
+	 * adding new variables should not invalidate VariableAccesor objects.
+	 *
+	 * If the VariableAccesor comes form a different Variables object or there
+	 * have been invalidating changes to this Variables object, behavior is not
+	 * well defined. You might get a NULL, a different variable than you
+	 * expected, or a segfault.
+	 */
+	template<typename T>
+	boost::shared_ptr<T> get_fast(const VariableAccesor<T>& a) const {
+		BOOST_MPL_ASSERT(( boost::mpl::count<types, T> ));
+		return get<T>(a.get_name());
+	}
+
 	/** Get a variable, possibly default-creatng it.
 	 *
 	 * Returns the variable with the given name, or, if it does not exist,
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 167604e830421a6612c5260df0de5c9cc9739020..f124748e7c22887d48314596d4a2b12a063972d4 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -11,6 +11,7 @@ add_executable(tests
 	main.cpp
 	position.cpp
 	values.cpp
+	varaccess.cpp
 	variables.cpp
 )
 
diff --git a/tests/varaccess.cpp b/tests/varaccess.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..663c60d7f254db5e740fffeff87506d6114b50e7
--- /dev/null
+++ b/tests/varaccess.cpp
@@ -0,0 +1,52 @@
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+
+#include <libwccl/variables.h>
+#include <libpwrutils/foreach.h>
+
+#include <iostream>
+
+using namespace Wccl;
+
+BOOST_AUTO_TEST_SUITE(varaccess);
+
+struct VAfx
+{
+	Variables v;
+	VAfx() {
+		v.put("a", new Bool(true));
+		v.put("b", new Bool(true));
+		v.put("c", new Bool(true));
+		v.put("bb", new Bool(true));
+		v.put("aa", new Position(1));
+		v.put("aaa", new Position(2));
+	}
+};
+
+
+BOOST_FIXTURE_TEST_CASE(access, VAfx)
+{
+	std::vector<std::string> vnames;
+	vnames.push_back("a");
+	vnames.push_back("b");
+	vnames.push_back("c");
+	vnames.push_back("bb");
+	foreach (const std::string vn, vnames) {
+		VariableAccesor<Bool> a1 = v.create_accesor<Bool>(vn);
+		BOOST_CHECK(v.get_fast(a1) == v.get<Bool>(vn));
+		v.set("a", Bool(false));
+		BOOST_CHECK(v.get_fast(a1) == v.get<Bool>(vn));
+		v.put("a", Bool(true));
+		BOOST_CHECK(v.get_fast(a1) == v.get<Bool>(vn));
+	}
+}
+
+BOOST_FIXTURE_TEST_CASE(badaccess, VAfx)
+{
+	BOOST_CHECK_THROW(v.create_accesor<Bool>("asd"), InvalidVariableName);
+	BOOST_CHECK_THROW(v.create_accesor<Bool>("aaa"), VariableTypeMismatch);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+