hsutter / cppfront

A personal experimental C++ Syntax 2 -> Syntax 1 compiler
Other
5.23k stars 224 forks source link

[SUGGESTION] Allow template parameters in () scope #1099

Open Parad0x84 opened 3 weeks ago

Parad0x84 commented 3 weeks ago

What if we could simply call a templated function without angle brackets. To be clear I'm not talking about implicitly deducing

Note: I'll write in cpp1 syntax simply because I'm not aware of templating in cpp2

template<>
void MyFunc(constexpr bool SomeFlag)
{
    if constexpr(SomeFlag)
        Foo();
    else
        Bar();
}

And you would call it like any non-templated function

    MyFunc(true);

My suggestion also could be interpreted as "Allow constexpr parameters" and templating would be just an implementation detail. Actually now I'm thinking about it, this could effectively eliminate template keyword entirely from cpp2. What do you think about it?

Will your feature suggestion eliminate X% of security vulnerabilities of a given kind in current C++ code? No

Will your feature suggestion automate or eliminate X% of current C++ guidance literature? Probably no, but might simplify API usage

Edit: Current cpp1 syntax for reference:

template<bool SomeFlag>
void MyFunc()
{
    if constexpr(SomeFlag)
        Foo();
    else
        Bar();
}
    MyFunc<true>();
bluetarpmedia commented 3 weeks ago

If I understand correctly, Cpp2 already provides what you're after:

MyFunc: (someFlag) = {

}

Which produces this C++ code:

auto MyFunc(auto const& someFlag) -> void{

}

which is the new/alternative C++ syntax for a template parameter.

gregmarr commented 3 weeks ago

It seems like you looking for a replacement for this using function parameters instead of template parameters.

template<bool SomeFlag = false>
void MyFunc()
{
  std::cout << "false\n";
}

template<> void MyFunc<true>()
{
  std::cout << "true\n";
}

int main()
{
    MyFunc<false>();
    MyFunc<true>();
}
Parad0x84 commented 3 weeks ago

@bluetarpmedia No, I intentionally used if constexpr so you can see my purpose. I'm not templating on type, I'm templating on value.

@gregmarr Correct, We wouldn't even need template keyword, it would be just this in cpp2

MyFunc(constexpr bool SomeFlag)  = {
    if constexpr(SomeFlag)
        Foo();
    else
        Bar();
}

Templates existed way before constexpr, so they didn't have the chance to do this

gregmarr commented 3 weeks ago

So another way to write this in C++ (and thus is something that cppfront could actually do) is to move the constexpr parameters to be non-type template parameters. This would only work if the parameter types are valid as NTTPs.

template<bool SomeFlag> void MyFunc() {
    if constexpr(SomeFlag)
        std::cout << "true\n";
    else
        std::cout << "false\n";
}

int main()
{
    MyFunc<true>();
    MyFunc<false>();
    constexpr bool flagTrue = true;
    MyFunc<flagTrue>();
    constexpr bool flagFalse = true;
    MyFunc<flagFalse>();
}

The main() is from testing on Compiler Explorer.

Parad0x84 commented 3 weeks ago

So another way to write this in C++ (and thus is something that cppfront could actually do) is to move the constexpr parameters to be non-type template parameters. This would only work if the parameter types are valid as NTTPs.

Correct, see edited section of the original post. What I'm saying is unless we are templating on type we don't need to explicitly write template at all. It could be just an implementation detail and also on caller site, it would simplify the syntax a bit. Caller doesn't necessarily needs to know if it's a template or not

Arguably we could also do same for type parameters as well, but I'm not very sure if it would be useful or not

gregmarr commented 3 weeks ago

Correct, see edited section of the original post.

Thanks for pointing that out.

gregmarr commented 3 weeks ago

Arguably we could also do same for type parameters as well, but I'm not very sure if it would be useful or not

Is that different that what's in the first comment?

Parad0x84 commented 3 weeks ago

Arguably we could also do same for type parameters as well, but I'm not very sure if it would be useful or not

Is that different that what's in the first comment?

Yeah, see currently we can only do it with auto. We could also do something like that

MyFunc(typename T param) = {
    param.Foo();
}

But I'm just exploring possibilities a bit, I'm not expecting this part to be useful, it probably won't. non-type template parameters is the main idea

gregmarr commented 3 weeks ago

Herb references P1045R1 constexpr parameters on page 34 of https://github.com/hsutter/708/blob/main/708.pdf

Parad0x84 commented 3 weeks ago

Herb references P1045R1 constexpr parameters on page 34 of https://github.com/hsutter/708/blob/main/708.pdf

Thanks, I was not aware of that, but that seems like only mentioning. Is it considered for cpp2 or standard C++? I would wanna see it in both

gregmarr commented 3 weeks ago

https://github.com/cplusplus/papers/issues/603 Support from EWG to move forward: https://github.com/cplusplus/papers/issues/1458#issuecomment-1802434801

Parad0x84 commented 3 weeks ago

cplusplus/papers#603 Support from EWG to move forward: cplusplus/papers#1458 (comment)

Great, unless we wanna do it for cpp2 before c++26, we can close this issue and move on