gpt4 book ai didi

c++ - 可变参数模板方法特化

转载 作者:行者123 更新时间:2023-11-30 03:16:18 29 4
gpt4 key购买 nike

这是我目前拥有的代码:

class Foo
{
public:
template<typename T, typename... Args>
void Function(T t1, Args... args){
// Definition
}

private:
template<typename T>
void Function(T t1){
// Definition
}
};

#include "header.h"

int main()
{
Foo foo;
foo.Function(1, 2, 3, 4, 5);
return 0;
}

工作正常。当我尝试将定义分离到 source.cpp 时,gcc 开始提示。我知道我必须专门化模板以分离定义,所以我尝试将下面的代码添加到头文件中:

template<>
void Foo::Function<int, int...>(int t1, int... args);

template<>
void Foo::Function<int>(int);

但没有成功。我错过了什么


编辑:gcc 错误信息:

header.h:15:28: error: expansion pattern ‘int’ contains no argument packs void Foo::Function(int t1, int... args);

header.h:15:48: error: expansion pattern ‘int’ contains no argument packs void Foo::Function(int t1, int... args);

最佳答案

您不能将 int... 用作参数包,因此这是行不通的。此外,要将源与定义分开,您必须完全指定模板,因此即使允许该语法,int... 也不会起作用。

解决这个问题的方法。

<强>1。使 Function 接受初始化列表。我们可以编写函数,使其接受 int 的初始化列表:

#include <initializer_list>

class Foo {
public:
void Function(int t1, std::initializer_list<int> t2);
};

void Foo::Function(int t1, std::initializer_list<int> t2) {
for(int i : t2) {
// stuff
}
}

现在,您可以非常轻松地调用 Function,甚至不需要模板化:

Foo f; 
f.Function(10, {1, 2, 3, 4, 5});

如果您在其他地方使用模板,您可以将参数包直接扩展到初始化列表中:

template<class... Args>
void invoke_foo(Foo& f, int first, Args... rest) {
f.Function(first, {rest...});
}

<强>2。使用 SFINAE 禁用所有非 int 重载。 我们可以禁用 Foo::Function 的所有重载,这些重载不仅接受 int

#include <type_traits>

class Foo {
public:
// Requires C++17 for std::conjunction
// You could write your own std::conjunction too if you'd prefer
template<class... Args>
auto Function(int t1, Args... t2)
-> std::enable_if_t<std::conjunction<std::is_same<Args, int>...>::value>
{
// stuff
}
};

这样做的缺点是非整数值不会自动转换为 int

关于c++ - 可变参数模板方法特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56448167/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com