The point is: is you function genmesh always  requiring from the user the definition of a and b points?
If the answer is yes, than you can dispatch on the type of those points:
julia> struct Point1D{T} <: FieldVector{1,T}
           x::T
       end
julia> struct Point2D{T} <: FieldVector{2,T}
           x::T
           y::T
       end
julia> genmesh(N::Int, a::Point1D, b::Point1D) = "1D mesh!"
genmesh (generic function with 1 method)
julia> genmesh(N::Int, a::Point2D, b::Point2D) = "2D mesh!"
genmesh (generic function with 2 methods)
julia> a = Point1D(0.0); b = Point1D(1.0);
julia> genmesh(100, a, b)
"1D mesh!"
julia> a = Point2D(0.0, 0.0); b = Point2D(1.0, 1.0);
julia> genmesh(100, a, b)
"2D mesh!"
but if, as in your example, you have default values for these a, and b  parameters, and providing them explicitly is optional, there is no way for dispatch to know if the user wants a 1D or 2D mesh, if it can provide only the number of points. Thus, then, you need to provide the dimension somehow. One way is to define two functions, genmesh1D, genmesh2D, other way is to provide two methods but require as a parameter the type of point (dimension) you want, which is what I did there.
Cleaner or not is something that you have to choose from a user point of view, in this case.