我是模板的新手,我正在尝试使用它们以避免重复非常相似的功能。
在下面的示例中,我制作了一个简单而小型的工作示例来显示我的问题。
特别是,我有两个 struct
(“solo”和“duo”)。这些结构有一个共同的成员(a),其中一个有一个特定的成员(b)。
然后我有一个模板函数,它可以采用任何一个结构并打印成员a …并且我希望它只有在结构类型为“duo”时才能打印成员b。
我做的方式(使用 std::is_same_v
)它没有编译。我读到可以使用专业化来做到这一点,但是我想知道是否没有更优雅的方法?因为那时我感觉失去了模板的优势……但可能我还没有获得模板的力量以及如何/如何使用它们。
非常感谢您的帮助!
#include <iostream>
#include <string>
#include <type_traits>
struct solo{
int a;
};
struct duo : solo{
int b;
};
template<class T>
void function(T test){
std::cout<< std::to_string(test.a);
if(std::is_same<T, duo>::value) std::cout<< std::to_string(test.b);
}
int main()
{
solo testS;
testS.a = 1;
function(testS);
}
原文由 Hugo 发布,翻译遵循 CC BY-SA 4.0 许可协议
要回答您关于模板的问题(尽管在这个特定的应用程序中,它不是正确的解决方案,原因有很多):
它不起作用的原因是模板实例化发生在编译时,然后唯一发生的事情是
std::is_same
的值是为模板参数计算的。因此,在function<solo>
的代码中就像
由于 --- 中没有成员
b
test
因此无法编译。为了让它工作,你需要两个模板,并在实例化模板时使用 SFINAE 选择正确的一个(并且由于函数模板不能部分特化,你需要编写如下内容,这真的是写两个的愚蠢方式重载。或者您可以完全专门化模板,但您不会使用
if_same
)。此外,请注意 is_same 查看变量的静态类型,因此如果您有一个
solo&
到一个duo
对象,它仍然会选择solo
.模板的一个不太愚蠢的用法是编写一个函数模板,它可以处理 任何 具有成员
int b
的类型。这使用了一个辅助元函数(一个结构,所以我们可以使用部分特化):(请注意,两个版本都假设有一个成员
a
,否则将无法编译)