C++ Rule 3574 does not check if the explicit return type can actually be made implicit

Noticed using latest version of SonarLint for Visual Studio (4.13.0.11687)

C++ Rule 3574 warns about not using explicit return type for lambdas. That’s great, unless you have a lambda which actually requires an explicit return type because detection is impossible. Below you find one example of this. In this case, you could avoid this by explicitly constructing the Login object instead, but this is just one example of the general problem:

 const Login DbUser = [this]() -> Login {
		if (someCondition()) {
			return m_InitialUserData.DBUser;
		}
		return {
			GetUsernameFromSomePlace(), GeneratePassword()
		};
	}();

If you would remove -> Login in this example, the compile would fail. In VS: “a brace-enclosed list does not provide a return type for this lambda”.

As said though, this is just one example, there are plenty of reasons why auto-detection of a return type does not work. This rule only makes sense if the analyzer actually checks if the excplit trailing return type can be dropped.

Hello @awjan,

While I agree in your example Lambda return type deduction will not work as-is. I still believe it is a good practice to force the lambda return type to be deduced. As you suggested, this can be done by writing:
return Login { GetUsernameFromSomePlace(), GeneratePassword() };

Why:

The main reason why you should prefer to force return type deduction is to avoid implicit type conversion. Deduced return type doesn’t allow implicit type conversion.
For example, let’s not force type deduction and write the return type explicitly:

class AnyClass{
public:
operator Login(){...}
};

const Login DbUser = [this]() -> Login {
   	if (someCondition()) {
   		return AnyClass {}; // Implicit conversion allowed
   	}
   	return { GetUsernameFromSomePlace(), GeneratePassword() }; 
   }();

In this case, implicit conversion from AnyClass to Login is valid. No Complation error.

On the other hand, if we force type deduction:

class AnyClass{
public:
operator Login(){...}
};

const Login DbUser = [this]() {
   	if (someCondition()) {
   		return AnyClass {}; // Compilation error
   	}
   	return Login { GetUsernameFromSomePlace(), GeneratePassword() }; 
   }();

Implicit conversion in this case from AnyClass to Login is invalid. Complation error.

Let me know if you have further questions.

Abbas