Yes, it's perfectly valid to call a converting constructor in a return statement, if you use a braced-init-list to initialize the returned object.
The C++11 standard says this in 6.6.3 [stmt.return]:
The value of the expression is implicitly converted to the return type of the function in which it appears. A return statement can involve the construction and copy or move of a temporary object (12.2). [Note: A copy or move operation associated with a return statement may be elided or considered as an rvalue for the purpose of overload resolution in selecting a constructor (12.8). — end note] A return statement with a braced-init-list initializes the object or reference to be returned from the function by copy-list-initialization (8.5.4) from the specified initializer list. [Example:
std::pair<std::string,int> f(const char* p, int x) {
return {p,x};
}
— end example]
In the other commented-out return
statements you create a temporary object which would then need to be copied to the returned object, which requires an accessible copy ctor.