But I know Mathematica did not actually use any non-integer x in the fitting algorithm because if it had used, it would have encountered error: my basic functions are undefined for non-integer x.
It does throw an error as seen from the second example in your original post (emphasis is mine): "FindFit::fitm: Unable to solve for the fit parameters; the design matrix is nonrectangular, non-numerical, or could not be inverted." The same message is generated when non-integer x is present in the data:
FindFit[{{1., 1}, {2, 1}, {3, 1}, {4, 1}}, (a + 1) sin2[x] + b cos2[x], {a, b}, x];
FindFit::fitm: Unable to solve for the fit parameters; the design matrix is nonrectangular, non-numerical, or could not be inverted. >>
From this message I suppose that when y values aren't integers Mathematica does pass non-integer values for x to your basic functions, hence the error.
Hence un-restricting x to integers has NO real benefit/significance for the actual Mathematica's fitting algorithm.
You can find what the algorithm is by using Trace:
trace = Trace[FindFit[{1, 1, 1, 1}, (a + 1) sin2[x] + b cos2[x], {a, b}, x],
TraceInternal -> True];
trace[[6 ;;]]
From the output you see that in this case at first the objective function is evaluated for integer x, then real values for Sin and Cos are calculated and passed to PseudoInverse. It shouldn't be difficult to implement this algorithm yourself.
Or you can use FindMinimum as follows (note that y = 1. is non-integer):
sin2[n_Integer] := Sin[n]^2
cos2[n_Integer] := Cos[n]^2
FindMinimum[
Total[Table[(a + 1) sin2[x] + b cos2[x] - 1., {x, 1, 4}]^2], {a, b}]
{3.15853*10^-32, {a -> 0., b -> 1.}}
Alternatively you can relax your conditions as follows:
sin2[n_ /; FractionalPart[n] == 0] := Sin[n]^2
cos2[n_ /; FractionalPart[n] == 0] := Cos[n]^2
FindFit[{{1., 1.}, {2, 1}, {3, 1}, {4, 1}}, a sin2[x] + b cos2[x], {a, b}, x]
{a -> 1., b -> 1.}