How to avoid implicit conversions from integer 0 to pointer, as the element of a vector

Something like this? It's very similar to the overload solution you suggested, but requires wrapping the vector type. Fails to build if you provide a literal 0 because the deleted constructor overload is chosen.

#include <memory>
#include <new>
#include <vector>
#include <iostream>
using std::vector;

template<typename T>
struct no_zero {
        no_zero(T val) : val(val) {}
        no_zero(int val) = delete;
        operator T() { return val; }
        T val;
};

int func(const vector<no_zero<const char*> >& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

In hindsight many of the implicit conversions in C++ are unfortunate, this being one of them.

One option to consider is -Wzero-as-null-pointer-constant on gcc and clang. Be careful as this changes the behavior of standard programs and if enabled globally can have some unintended effects.

g++ - how do I disable implicit conversion from 0 to pointer types?

Which Clang warning is equivalent to Wzero-as-null-pointer-constant from GCC?


I like Mikel Rychliski's answer. However there already exists a solution in Guideline Support Library:

gsl::not_null

I highly recommend GSL. It's created and backed by many C++ experts, Bjarne Stroustrup himself and Herb Sutter among them. And the C++ Core Guidelines are actively being integrated into the compiler warnings and static analyzers.