我可以将单个模板<typename T> 应用于多个定义/声明吗?

Posted

技术标签:

【中文标题】我可以将单个模板<typename T> 应用于多个定义/声明吗?【英文标题】:Can I make a single template<typename T> apply to multiple definitions/declarations? 【发布时间】:2015-10-26 11:19:52 【问题描述】:

在 C++ 中,我想说:

template <typename T> 
void foo(T t1);
void bar(T t1, T t2);

即让template &lt;typename T&gt; 应用于多个定义/声明。上面的 语法无法编译;有没有其他表达方式?

注意:将函数包装在结构/类中是不行的,我想要一些既简洁又没有任何虚拟实体的东西。

【问题讨论】:

不,没有这样的独角兽。 如果你可以等待,你可以使用 C++17 概念中的auto 参数类型。 @CoffeeandCode: 好吧,看看我现在没有这个是如何生活的,我想我可以等待 :-) 但是 C++17 auto 的更改将如何解决这个问题?如果你把它变成一个答案,我可以投票...... 如果你愿意,我给你写一点,总得拖延一下吧! @CoffeeandCode: 请这样做:-) 【参考方案1】:

如果您可以等待C++17 concepts,您可以使用auto 参数类型而不是使用模板。

假设我有以下 C++17 函数:

auto func(auto x, auto y)
    return x + y;

这可以像这样用 C++14 重写:

template<typename T, typename U>
auto func(T x, U y)
    return x + y;

可以像这样在 C++11 中再次重写:

template<typename T, typename U>
auto func(T x, U y) -> typename std::decay<decltype(x + y)>::type
    return x + y;

作为@T.C.在 cmets 中声明,std::decay 在这里是必要的,因为 c++14 中自动返回类型的语义将衰减最终语句,而 decltype(x + y) 不会衰减表达式类型。如果我们不想衰减返回表达式类型,我们会写:

// template here for c++14
decltype(auto) func(auto x, auto y)
    return x + y;

因此,鉴于这些信息,我们可以像这样重写您的函数:

void foo(auto t1);
void bar(auto t1, auto t2);

请记住,如果我们需要引用参数的类型,我们将需要使用 decltype


如果您打算广泛使用类型,模板是一个更好的主意,但为了在函数定义中保持函数声明的简洁性,我们可以为这些类型编写一些 using 语句:

void bar(auto t1, auto t2)
    using type_t1 = std::decay_t<decltype(t1)>;
    using type_t2 = std::decay_t<decltype(t2)>;

如果我们通过一些 cv 限定符传入指针或引用,就会出现在这种情况下对 std::decay_t 的需求。我们只需要底层类型。

然后强制type_t1type_t2 的基础类型与您的示例中的相同,我们可以使用SFINAE 排除bar 的任何实例化,但它们不是:

auto bar(auto t1, auto t2) -> std::enable_if_t<std::is_same<std::decay_t<decltype(t1)>, std::decay_t<decltype(t2)>>::value>
    using type = std::decay_t<decltype(t1)>;

再次,衰减类型,以便如果我们得到指针,我们正在比较底层类型。

记得问问自己,这一切是否值得,因为不必再写几次template&lt;typename T&gt;

【讨论】:

(不是反对者)您的 C++14 和 C++11 版本不一样。此外,最后的 sfinae 相当荒谬。 @T.C.为何如此?如果你让我知道怎么做,我会纠正它 您的 C++11 版本,模 SFINAE,相当于在 C++14 中返回 decltype(auto)。返回 auto 会衰减类型。 @T.C.谢谢,我会解决的

以上是关于我可以将单个模板<typename T> 应用于多个定义/声明吗?的主要内容,如果未能解决你的问题,请参考以下文章

template<typename T>:只允许使用静态数据成员模板

C++模板typename关键字的用法

C++模板typename关键字的用法

C++ TGP 模板基础知识--函数模板

我们可以将 Q_PROPERTY 与 template<typename T> 一起使用吗?

模板参数在具有相同数据类型的单个typename的构造函数中不起作用