Proposal for explict keyword for non constructor functions

So we have the explicit specifier for constructors, would it be better if we could have explicit for any type of callable functions as well. At the moment we can use a template function where the template parameters are set to a specific type:

1
2
3
4
template <typename T = double>
T f(T) {
// ...
}


I would also like to avoid using RTTI for this purpose.

So I think it would be better to have the syntatic sugar, this usage meaning that all the parameters have to be explicit:

1
2
3
explicit void f(double input) {
// ...
}


Going further, we could have the explicit being optional for some of the function parameters:

1
2
3
void f(explicit double input, float other) {
// ...
}


While we are at it, I propose to have a way of turning off implicit type conversion, maybe with a #pragma and/or a compiler option? The #pragma would be for Translation Unit level control, while the compiler option would be global. Implicit type conversions are the source of many errors according to Jason Turner.

Any thoughts?
Last edited on
Can you explain the difference in behavior on the calling side?

Edit: Ah, you mean, if foo was explicit, this would not compile:
1
2
3
4
5
void foo(double bar) { }

int main() {    
    foo((char)42);
}


Seems like a good proposal to me, but if you're serious about trying to get a new proposal into the language,
you should look at https://isocpp.org/std/submit-a-proposal
Last edited on
@Ganado

Cheers, I am aware of the iso cpp site, I wanted to see what people thought, just in case someone had a better idea.

I have seen the documentation about user conversion functions, but it would seem a pain to have to create those, and they are for class types, I would like them for any callable.


https://en.cppreference.com/w/cpp/language/cast_operator.html
IMO anything which can detect 'issues' at compile time is to welcomed.
Cheers seeplus

Also kind of related to this is the idea of list initialising function arguments with braces to warn if there is narrowing:

1
2
3
4
5
6
7
8
9
int foo(int input) {return input;}

int main() {

double a{2.0};

int b = foo({a}); // error narrowing of type

}


But this is a bit limiting, I would like something more greedy.
Apparently the best workarounds for this are to use strong types and explicit constructors everywhere; or the use of concepts to require certain types.

But this is a problem for existing code bases, it would be a big job to change to strong types; whereas an explicit specifier for all callables would be much easier, I imagine.
Also, using concepts implies using templates, no? And templates just make everything more verbose, longer to compile, and harder to reason about. That is to say, I think there would still be a place for an explicit parameter feature even with concepts.

I wonder what some of those wrappers on top of C or C++ behave like by default; do they prevent this situation at compile-time?
Last edited on
@Ganado

Yes I agree, templates often make things harder.

Yes, it is my understanding that concepts work at compile time.
I was actually referring to (what I have since looked up as) "Cpp2", which is compiled using a "CppFront" compiler. In other words, it is a language that translates directly into the underlying C++ before being actually compiled. I believe Herb Sutter developed it. I doubt it has any wide adoption, but it's an interesting concept.

I know Cpp2 makes constructors explicit by default, with the option of making them "implicit" as a keyword. I don't know if the same applies to functions, or how implicit conversions happen in general in Cpp2.
https://hsutter.github.io/cppfront/cpp2/types/
Last edited on
I have been a fan of cpp2, since Herb started it; I like the whole idea of it.

I imagine if cpp2 translates into existing c++, it would have to do some of the workarounds we have mentioned. I don't know if callables are explicit in cpp2.
Registered users can post here. Sign in or register to post.