cppfront icon indicating copy to clipboard operation
cppfront copied to clipboard

[SUGGESTION] Allow template parameters in () scope

Open Parad0x84 opened this issue 1 year ago • 12 comments

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>();

Parad0x84 avatar Jun 06 '24 05:06 Parad0x84

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.

bluetarpmedia avatar Jun 06 '24 07:06 bluetarpmedia

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>();
}

gregmarr avatar Jun 06 '24 14:06 gregmarr

@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

Parad0x84 avatar Jun 06 '24 18:06 Parad0x84

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.

gregmarr avatar Jun 06 '24 21:06 gregmarr

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

Parad0x84 avatar Jun 06 '24 21:06 Parad0x84

Correct, see edited section of the original post.

Thanks for pointing that out.

gregmarr avatar Jun 06 '24 21:06 gregmarr

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?

gregmarr avatar Jun 06 '24 21:06 gregmarr

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

Parad0x84 avatar Jun 06 '24 21:06 Parad0x84

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

gregmarr avatar Jun 06 '24 21:06 gregmarr

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

Parad0x84 avatar Jun 06 '24 21:06 Parad0x84

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

gregmarr avatar Jun 06 '24 21:06 gregmarr

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

Parad0x84 avatar Jun 07 '24 00:06 Parad0x84