Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial specialization or instantiation of template class method

Tags:

c++

templates

I have template struct with several template parameters

template<class Result, class T, class K>
struct MyClass
{
public:
    Result foo()
    {
        return Result{};
    }
};

This struct works fine for all templates except the case when Result is void. I understand, that Result{} cannot be implemented to void type, so my current solution is to use partial specialization like this:

template<class T, class K>
struct MyClass<void, T, K>
{
public:
    void foo()
    {
        return;
    }
};

This allows to do following:

int main()
{
    MyClass<void, double, char> mycl1;
    MyClass<int, double, char> mycl2;

    mycl1.foo();
    mycl2.foo();
}

Is there a way to make mycl1.foo() compile without partial class specialization in C++ 14 standart? I could use if constexr and type trait is_void_v combination, but I want to find if there is a way to:

  • specialization of template class method partial explicit

  • instantiation of template class method

like image 605
Demaunt Avatar asked Apr 16 '19 19:04

Demaunt


1 Answers

While you cannot do

Result foo()
{
    return Result{};
}

If Result is void, you can use

Result foo()
{
    return Result();
}

The behavior in this case is the same and you will get a value initialized object returned. This syntax is allowed when Result is void by [expr.type.conv]\2

If the initializer is a parenthesized single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression. If the type is cv void and the initializer is (), the expression is a prvalue of the specified type that performs no initialization. Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized with the initializer. For an expression of the form T(), T shall not be an array type.

Coming soon though you will be able to use

return Result{};

even if Result is void as C++20 added to that section that {} will work as well for void. [expr.type.conv]\2 now states

If the initializer is a parenthesized single expression, the type conversion expression is equivalent to the corresponding cast expression. Otherwise, if the type is cv void and the initializer is () or {} (after pack expansion, if any), the expression is a prvalue of the specified type that performs no initialization. Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized with the initializer. If the initializer is a parenthesized optional expression-list, the specified type shall not be an array type.

like image 108
NathanOliver Avatar answered Oct 14 '22 17:10

NathanOliver