C++ 如何混合使用非类型模板参数和类型模板参数来模板化函数?
最小可重复示例C++ 如何混合使用非类型模板参数和类型模板参数来模板化函数?,c++,templates,C++,Templates,最小可重复示例 #include <unordered_map> #include <string> template<class T, bool did_work> class Test { Test(T input) : field(input), success(did_work) {} T field; bool success; }; template<typename A> void func(std::un
#include <unordered_map>
#include <string>
template<class T, bool did_work>
class Test {
Test(T input) : field(input), success(did_work) {}
T field;
bool success;
};
template<typename A>
void func(std::unordered_map<std::string, Test<A, bool>> input1, A input2) {}
int main() {}
#包括
#包括
样板
课堂测试{
测试(T输入):字段(输入),成功(是否工作){
T场;
成功;
};
样板
void func(std::无序_映射input1,A input2){}
int main(){}
输出:
$ g++ -std=c++17 -ggdb -g3 -Wall test.cpp && ./a.out
test.cpp:12:51: error: type/value mismatch at argument 2 in template parameter list for ‘template<class T, bool did_work> class Test’
12 | void func(std::unordered_map<std::string, Test<A, bool>> input1, A input2) {}
| ^~~~
test.cpp:12:51: note: expected a constant of type ‘bool’, got ‘bool’
test.cpp:12:55: error: template argument 2 is invalid
12 | void func(std::unordered_map<std::string, Test<A, bool>> input1, A input2) {}
| ^~
test.cpp:12:55: error: template argument 5 is invalid
$g++-std=c++17-ggdb-g3-Wall test.cpp&./a.out
test.cpp:12:51:错误:“模板类测试”的模板参数列表中参数2的类型/值不匹配
12 | void func(标准::无序映射输入1,A输入2){
| ^~~~
test.cpp:12:51:注:应为'bool'类型的常数,得到'bool'
test.cpp:12:55:错误:模板参数2无效
12 | void func(标准::无序映射输入1,A输入2){
| ^~
test.cpp:12:55:错误:模板参数5无效
我需要能够传入无序映射
以及无序映射
。在函数定义中是否有方法在不更改类测试定义的情况下执行此操作?带模板的did_work
是非类型模板参数。这意味着它不向它传递类型,而是接受一个值。因为它需要一个值,所以您可以像Test
或Test
那样进行Test
,而不是Test
对于您的函数,您只需添加一个非类型模板参数即可
template<typename A, bool did_work>
void func(std::unordered_map<std::string, Test<A, did_work>> input1, A input2) {}
模板
void func(std::无序_映射input1,A input2){}
这样做:
#include <unordered_map>
#include <string>
template<class T, bool did_work>
class Test {
Test(T input) : field(input), success(did_work) {}
T field;
bool success;
};
template<typename A, bool b = true>
void func(std::unordered_map<std::string, Test<A, b>> input1, A input2)
{
}
int main() {
}
#包括
#包括
样板
课堂测试{
测试(T输入):字段(输入),成功(是否工作){
T场;
成功;
};
样板
void func(标准::无序映射输入1,A输入2)
{
}
int main(){
}
使现代化
我的意思是你写的东西像:
#include <unordered_map>
#include <string>
#include <iostream>
template<class T, bool did_work>
class Test {
public:
Test(T input) : field(input), success(did_work) {}
private:
T field;
bool success;
};
template<
typename UnorderedMap
,typename A
> requires requires (UnorderedMap map){
map.size();
}
void func(
UnorderedMap input1,
A input2)
{
std::cout << input1.size();
}
int main()
{
using A = int;
Test<A, true> t{12};
std::unordered_map<std::string, Test<A, true>> map{};
func(map, 12);
//this would fail!
//func(12, 12);
}
#包括
#包括
#包括
样板
课堂测试{
公众:
测试(T输入):字段(输入),成功(是否工作){
私人:
T场;
成功;
};
模板<
typename无序映射
,键入名称A
>需要(无序映射){
map.size();
}
无效函数(
无序映射输入1,
A输入2)
{
std::cout因此,如果不定义函数的两个实例,就没有办法解决这个问题,一个是执行Test
,另一个是执行Test
?@ajoseps刚刚添加到答案中,说明了如何调整模板以同时执行这两个实例。但一般来说,您应该避免这样严格的类型要求。我会使用概念/约束或SFINAE如果你有一些要求。你介意扩展概念/约束或SFINAE方法吗?我对这些不太熟悉。此外,你不应该使用“按价值”的方法容器的参数-这可能很昂贵…你能解释一下为什么这可能很昂贵吗?如果你按值传输大型对象,你可能需要复制大量数据