【问题标题】:Is there a way to name a type for a function template specialization?有没有办法为函数模板专业化命名类型?
【发布时间】:2014-04-28 18:48:59
【问题描述】:

例如,当我们有一个通用的函数模板时,我们可以在函数中使用模板类型:

template <typename T>
void foo()
{
  T t;
  ...
}

现在,想象一下这个函数模板的特化:

template <>
void foo<MySpecialType>()
{
  T t; // Does not compile, no knowledge of formal template argument T
  MySpecialType t2; // This is OK, but I have to mention MySpecialType again
}

template <>
void foo<MySpecialType2>()
{
  T t; // Does not compile, no knowledge of formal template argument T
  MySpecialType2 t2; // This is OK, but I have to mention MySpecialType2 again
}

请注意,在上述两种特化中,我必须提到在函数体内按名称特化的模板参数的类型。我宁愿使用更通用的占位符(即 T),而不是在函数模板特化的主体中重复(可能多次)被特化的类型。

如果有一种方法可以在实际的专业化函数定义处使用 T 或创建别名,那就太好了。我知道我可以通过实际函数体内的类型别名来做到这一点:

template<>
void foo<MySpecialType>
{
  using T=MySpecialType; // But then I still repeat the type at least once
  ...

我更喜欢这样的专业化约定:

// Warning: Not valid C++
template<>
void foo<T=MySpecialType>
{
  T t;
  ...

或者:

// Warning: Not valid C++
template<T>
void foo<MySpecialType>
{
  T t;
  ...

感谢您的建议。

【问题讨论】:

  • T 在这种情况下会是什么?
  • 我很好奇你为什么关心这个。我并不是要轻率——我怀疑我知道为什么,这可能会影响如何最好地解决这个问题。
  • 你是说让复制粘贴代码编写更容易吗?
  • @John,我指的是每个专业都按名称提及一个类型。由于每个专业化都针对不同的类型,因此必须至少提及其类型一次。我想看看这个“至少一次”是否也可以变成“最多一次”,以避免通过名称提及多余的类型。
  • 此外,您似乎正在将非专业化的实现视为您在专业化中尝试实现的标准。但是你必须在那里“提及”T 至少两次。

标签: c++ templates c++11


【解决方案1】:

你可以这样做:

template <typename T>
struct bar
{
    using Type = T;

    static void foo();
};

template <typename T>
void bar<T>::foo()
{
    Type t;
    // ...
}

template <>
void bar<MySpecialType>::foo()
{
    Type t;
    // ...
}

template <>
void bar<MySpecialType2>::foo()
{
    Type t;
    // ...
}

template <typename T>
void foo()
{
    bar<T>::foo();
}

但是你真的需要它吗?

【讨论】:

  • 这似乎根本没有回答问题?
  • @JohnDibling 为什么?现在可以在bar&lt;...&gt;::foo() 专业化中使用Type
  • 您似乎在回答这个问题,“我如何专门化一个模板?”那不是问题。也许我误解了某人。
  • @JohnDibling 我回答了“如何以统一的方式在模板专业化中获取模板参数类型”的问题。我的解决方案使用辅助类和其中的using Type = T; 指令来实现这一点。
  • @JohnDibling 我在答案中添加了几行代码。拜托,看清楚了吗?
【解决方案2】:

这是可行的。以下是一个使用部分特化的工作解决方案,并且是一个包含静态函数的类模板:

template<typename T, typename U = void>
struct foo_impl
{
    static void bar()
    {
        ::std::cout << "T\n";
    }
};

template<typename T>
struct foo_impl<T, typename ::std::enable_if<::std::is_same<T, int>::value>::type>
{
    static void bar()
    {
        ::std::cout << "int\n";
    }
};

template<typename T>
void foo()
{
    foo_impl<T>::bar();
}

【讨论】:

  • ::std::enable_if&lt;::std::is_same:这是一个有向图。代码不应编译。
  • @Constructor 除非你使用 c++11
  • 你能提供一个链接吗?
  • @Constructor A GCC bug report 引用了标准的确切部分:2.5§3 bullet 2
  • 感谢您的链接!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 2013-10-27
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多