To allow for one template argument you need to default the second one to something, e.g. nullptr
:
template<typename T, list_node T::* node = nullptr> class linked_list;
Now you can specialize linked_list<T, nullptr>
template that is used when the second template argument is nullptr
:
template<typename T> class linked_list<T, nullptr>;
The above specialization does not work. An alternative way to specialize (complete working example):
struct list_node {};
struct X { list_node node; };
template<typename T, list_node T::*P, bool Special>
struct linked_list_ {};
template<typename T, list_node T::*P>
struct linked_list_<T, P, true> {};
template<typename T, list_node T::*P = nullptr>
struct linked_list
: linked_list_<T, P, static_cast<list_node T::*>(nullptr) == P>
{};
int main() {
linked_list<X, &X::node> a; // uses linked_list_<T, P, false>
linked_list<X> b; // uses linked_list_<T, P, true>
}