I'm hoping to get some feedback on a function with variadic templates that parses a format string and fills in some parameters whose order and types are based on the characters in the format string. Kind of like scanf().
(For the curious, I am trying to make a typesafe version of this function, documentation here.)
I'm pretty experienced with C but the last time I did anything serious with C++ was at university 15 years ago and it seems like a completely different language now.
This toy code works for me and fails in the ways I'd expect it to when I give it bad input. However, I'm not too familiar with the standard library so I have a strong feeling that I may be missing something. Also the code seems overly verbose for what it does.
So here's what I'm hoping to find out:
- Is this code idiomatic modern C++?
 - Am I overlooking useful features in the standard library that would make things easier?
 - Should I be using pointers in this way, or am I thinking too much in C?
 - Should I consider another approach entirely, like 
tscanf(format, paramname1, paramname2) >> param1 >> param2? 
I am constrained to use C++11, the code currently does not use Boost.
#include <cstring>
#include <iostream>
struct SomeStruct {
    int val;
};
template<typename T>
bool
assign(const char c, T& ref) {
    return false;
}
template<>
bool
assign(const char c, bool*& ref) {
    if (c != 'b')
        return false;
    *ref = true;
    return true;
}
template<>
bool
assign(const char c, int*& ref) {
    if (c != 'i')
        return false;
    *ref = 42;
    return true;
}
template<>
bool
assign(const char c, SomeStruct& ref) {
    if (c != 'h')
        return false;
    ref.val = 81;
    return true;
}
template<typename T>
bool
tscanf(const char *format, const char *name, T& ref)
{
    if (std::strlen(format) != 1) {
        std::cerr << "Wrong number of arguments" << std::endl;
        return false;
    }
    if (!assign(format[0], ref)) {
        std::cerr << "Wrong type for argument " << name << std::endl;
        return false;
    }
    return true;
}
template<typename T, typename... Args>
bool
tscanf(const char *format, const char *name, T& ref, Args... args)
{
    if (!assign(format[0], ref)) {
        std::cerr << "Wrong type for argument " << name << std::endl;
        return false;
    }
    return tscanf(format + 1, args...);
}
int
main(void)
{
    bool b;
    int i;
    SomeStruct h;
    if (!tscanf("hbi",
        "handle", h,
        "switch", &b,
        "num", &i))
        return 1;
    std::cout << h.val << ' ' << b  << ' ' << i << std::endl;
    return 0;
}