gpt4 book ai didi

c++ - 具有多个条件的默认模板特化

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:43 25 4
gpt4 key购买 nike

我想为整数类型、字符串和其他类型定义函数。

我会写:

template<typename T, typename = std::enable_if<std::is_integral<T>::value>::type>
void foo();

template<typename T, typename = std::enable_if<std::is_same<std::string>::value>::type>
void foo();

但是我如何定义将在其他情况下调用的函数(如果 T 不是整型且不是 std::string)?

最佳答案

我敢肯定,当您想编写多达 N 个 sfinae 版本的 foo 时,编写类似下面这行的内容会变得非常烦人且容易出错。 :

std::enable_if<!std::is_integral<T>::value && !std::is_same<T, std::string>::value>::type

要避免它,您可以使用选择技巧(一种实际利用重载决议的简单方法)。
它遵循一个最小的工作示例:

#include <iostream>
#include <utility>
#include <string>

template<int N> struct Choice: Choice<N-1> {};
template<> struct Choice<0> {};

template<typename T, typename... Args>
std::enable_if_t<std::is_integral<T>::value>
bar(Choice<2>, Args&&...) { std::cout << "integral" << std::endl; }

template<typename T, typename... Args>
std::enable_if_t<std::is_same<T, std::string>::value>
bar(Choice<1>, Args&&...) { std::cout << "string" << std::endl; }

template<typename T, typename... Args>
void bar(Choice<0>, Args&&...) { std::cout << "whatever" << std::endl; }

template<typename T, typename... Args>
void foo(Args&&... args) { bar<T>(Choice<100>{}, std::forward<Args>(args)...); }

int main() {
foo<bool>("foo");
foo<std::string>(42);
foo<void>(.0, "bar");
}

它还可以很好地处理从集合中提取后直接转发给正确函数的参数。

基本思想是它尝试按照您指定的顺序使用函数的所有版本,从 N 到 0。这还有一个好处,您可以将优先级设置为当其中两个匹配模板参数时起作用 T用他们的 sfinae 表达。
sfinae 表达式启用或禁用第 i 个选择,您可以使用 Choice<0> 轻松定义回退标签(这比 std::enable_if<!std::is_integral<T>::value && !std::is_same<T, std::string>::value>::type 更容易写)。
缺点(即使我不认为这是缺点)是它需要一个额外的函数,通过将参数附加到 Choice<N> 来简单地将参数转发到链中。标签。

Coliru 上查看它的启动和运行情况.

关于c++ - 具有多个条件的默认模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45502322/

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