我有带有几个模板参数的模板结构
template<class Result, class T, class K>
struct MyClass
{
public:
Result foo()
{
return Result{};
}
};
此结构对所有模板都适用,但Result为空的情况除外。
我了解,Result{}
无法实现为void类型,所以我目前的解决方案是使用部分专业化功能,如下所示:
template<class T, class K>
struct MyClass<void, T, K>
{
public:
void foo()
{
return;
}
};
这允许执行以下操作:
int main()
{
MyClass<void, double, char> mycl1;
MyClass<int, double, char> mycl2;
mycl1.foo();
mycl2.foo();
}
有没有一种方法可以使mycl1.foo()
在C ++ 14标准中没有部分类专门化的情况下进行编译?我可以使用if constexr
并键入特征is_void_v
组合,但是我想找到是否有办法:
模板类方法的专业化(部分显式)
模板类方法的实例
答案 0 :(得分:7)
虽然不能做
Result foo()
{
return Result{};
}
如果Result
是void
,则可以使用
Result foo()
{
return Result();
}
在这种情况下,行为是相同的,并且您将获得一个返回值的初始化对象。当[expr.type.conv]\2的Result
为void
时,可以使用此语法
如果初始化程序是带括号的单个表达式,则类型转换表达式与相应的转换表达式等效(在定义上,如果含义明确)。如果类型为cv void,并且初始值设定项为(),则表达式是不执行初始化的指定类型的prvalue。否则,表达式是指定类型的prvalue,其结果对象使用初始化程序直接初始化。对于形式为T()的表达式,T不得为数组类型。
尽管很快就能使用
return Result{};
即使Result
是void
,因为C ++ 20已添加到该部分,{}
也将对void
起作用。 [expr.type.conv]\2现在声明
如果初始化程序是带括号的单个表达式,则类型转换表达式与相应的强制转换表达式等效。否则,如果类型为cv void且初始化器为()或{}(在包扩展后,如果有的话),则表达式为指定类型的prvalue,不执行初始化。否则,表达式是指定类型的prvalue,其结果对象使用初始化程序直接初始化。如果初始化程序是带括号的可选表达式列表,则指定的类型不得为数组类型。