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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With