Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何混合使用非类型模板参数和类型模板参数来模板化函数?_C++_Templates - Fatal编程技术网

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方法吗?我对这些不太熟悉。此外,你不应该使用“按价值”的方法容器的参数-这可能很昂贵…你能解释一下为什么这可能很昂贵吗?如果你按值传输大型对象,你可能需要复制大量数据