Consider a struct with static method templates that accept pointer-to-member functions. Note that when one of the arguments to the methods is an actual pointer-to-member function, both template parameters can be deduced, regardless if the other argument is a nullptr or not.
See questions below the following code:
struct Checker
{
    template <typename T, typename V>
    static void Check(
        V(T::*getter)(),
        void(T::*setter)(V)
    );
    template <typename T, typename V>
    static void CheckDefault(
        V(T::*getter)() = nullptr,
        void(T::*setter)(V) = nullptr
    );
};
struct Test
{
    int Value();
    void Value(int);
    int Getter();
    void Setter(int);
};
Checker::CheckDefault(&Test::Value);           //1
Checker::CheckDefault(&Test::Value, nullptr);  //2
Checker::Check(&Test::Value, nullptr);         //3
Checker::CheckDefault(&Test::Getter);          //4
Checker::CheckDefault(&Test::Getter, nullptr); //5
Checker::Check(&Test::Getter, nullptr);        //6
- Why can the correct overload of 
&Test::Valuebe determined in 1, but not in 2 and 3? - Why are 1 and 4 able to deduce the correct typenames, but 2, 3, 5 and 6 not?
 
Edit
I was expecting to be able to call the methods with at least one of the two arguments set to an actual pointer-to-member function, causing deduction to succeed. Like so:
Checker::Check(&Test::Value, &Test::Value); // Both getter and setter
Checker::Check(&Test::Value, nullptr); // Only getter
Checker::Check(nullptr, &Test::Value); // Only setter
Edit
The discussion in the excepted answer by @Oliv explaining why it doesn't work as I expected, pointed me in the right direction for solving my specific problem.
I ended up using forwarders, as @Ben Voigt suggested. Something like:
template <typename T, typename V>
using GetterT = V(T::*)();
template <typename T, typename V>
using SetterT = void(T::*)(V);
template <typename T, typename V>
void Checker::CheckGetterAndSetter(
    GetterT<T, V> getter,
    SetterT<T, V> setter
)
{
    // Do stuff with getter and setter.
}
template <typename T, typename V>
void Checker::CheckGetter(
    GetterT<T, V> getter
)
{
    SetterT<T, V> null = nullptr;
    return CheckGetterAndSetter(getter, null);
}
template <typename T, typename V>
void Checker::CheckSetter(
    SetterT<T, V> setter
)
{
    GetterT<T, V> null = nullptr;
    return CheckGetterAndSetter(null, setter);
}