简体   繁体   English

如何使用非类型模板参数和类型模板参数的混合来模板化函数?

[英]How to template a function with a mix of non-type template parameters and type template parameters?

Minimal Reproducible Example最小可重复示例

#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() {}

Output:输出:

$ 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

I need to be able to pass in unordered_map<std::string, Test<A, true>> as well as unordered_map<std::string, Test<A, false>> .我需要能够传入unordered_map<std::string, Test<A, true>>以及unordered_map<std::string, Test<A, false>> Is there a way to do this in the function definition without changing the class Test definition?有没有办法在不更改类Test定义的情况下在函数定义中执行此操作?

With template<class T, bool did_work> did_work is a non-type template parameter.使用template<class T, bool did_work> did_work是非类型模板参数。 What that means is that instead of passing a type to it, it takes a value.这意味着它不是将类型传递给它,而是需要一个值。 Since it needs a value, you make a Test like Test<A, true> or Test<A, false> , not Test<A, bool> .由于它需要一个值,因此您可以进行Test Test<A, true>Test<A, false> Test<A, bool> ,而不是Test<A, bool>

For your function you can just add a non-type template parameter to do this for you like对于您的功能,您只需添加一个非类型模板参数即可为您执行此操作

template<typename A, bool did_work>
void func(std::unordered_map<std::string, Test<A, did_work>> input1, A input2) {}

Do it like this:像这样做:

#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() {

}

Update更新

I mean that you write something like:我的意思是你写这样的东西:

#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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM