Hello!
So yes we did do this and have a library (may be too strong a word) to help us do this.
A quick warning that I wrote this when our coderunner install only went up to C++14, I do have plans to rewrite for C++17 as it will make the code sooooo much cleaner but that hasn't happened yet.
Secondly I wrote this for my own personal use so the process is messy as hell. I actually write my questions in yaml files which then get converted into C++ programs that I can run locally and moodle XML files that I can upload for coderunner.
So I am sharing the whole thing here. This includes:
- Some example questions (not all involving functions) written in the yaml format, e.g. practise_is_teenager.yaml
- The converted yaml files in .cpp (for running on local machines) e.g. practise_is_teenager.cpp
- The converted yaml files in moodle format for upload, all questions are in moodle.xml
- The script for converting the yaml, parseyaml.py
- And the library files, e.g. all_func_testing.h
But re. your specific question, testing for number of arguments. This is the code you need, which will also do things like give you details of the return type, argument types and whether it is, in fact, a function.
#include <iostream>
#include <tuple>
template<typename T>
struct function_traits
{
static constexpr size_t version = 0;
static constexpr size_t nargs = 0;
typedef T return_t;
template<size_t i>
struct arg { typedef std::nullptr_t type; };
};
template<typename R>
struct function_traits<R()>
{
static constexpr size_t version = 1;
static constexpr size_t nargs = 0;
typedef R return_t;
template<size_t i>
struct arg { typedef std::nullptr_t type; };
};
template<typename R, typename ...Args>
struct function_traits<R(Args...)>
{
static constexpr size_t version = 2;
static constexpr size_t nargs = sizeof...(Args);
typedef R return_t;
template<size_t i>
struct arg
{
using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
};
void student_function( int a, int b, int c ){}
int main()
{
using traits_t = function_traits<decltype(student_function)>;
std::cout << "Number of arguments: " << traits_t::nargs << std::endl;
return 0;
}
Regards
David