【问题标题】:Proper way to write a C++17 style "_v" helper template for a nested template为嵌套模板编写 C++17 样式“_v”帮助器模板的正确方法
【发布时间】:2020-01-30 17:29:32
【问题描述】:

标准库提供模板来在编译时确定不同的类型特征。例如:

std::is_integral<T>::value 会告诉你某个东西是否是整数类型。

从 C++17 开始,为这些类型特征模板添加了快捷方式“帮助模板”。

std::is_integral_v<T> 提供相同的结果而不需要::value


类似于std::is_integral,我有一个比较复杂的模板来判断一种类型是否是另一种类型的特化:

template <typename T, template <typename...> typename Template>
struct is_specialization : std::false_type {};

template <template <typename...> typename Template, typename... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};

一个使用示例如下所示(如果传入的类型是std::complex的特化,这将启用此模板功能):

#include <complex>
#include <iostream>
#include <type_traits>

template <typename T>
struct MyComplex
{
    MyComplex(const T& real, const T& imag)
        : real(real)
        , imag(imag)
    {}

    T real() { return this->real; }

    T imag() { return this->imag; }

private:
    T real;
    T imag;
};

// Only enable this template if "T" is a specialization of "std::complex"
template <typename T,
    typename = std::enable_if_t<is_specialization<T, std::complex>::value>
>
void foo(T value)
{
    std::cout << value.real() << std::endl;
}

int main()
{
    std::complex<double> value1{ 1.0, 2.0 };
    foo(value1);

    std::complex<int> value2{ 1, 2 };
    foo(value2);

    MyComplex<double> value3{ 1.0, 2.0 };

    // Fails to compile because "MyComplex<double>" is not a specialization of "std::complex"
    //foo(value3);
}

我想为此编写一个“_v”帮助模板,但我不确定如何,因为它涉及嵌套模板。

由于is_specialization 有两个模板参数,我的第一个想法是做这样的事情,也许编译器会发现“T”和“U”可以自己嵌套类型,但它不是似乎工作:

template <typename T, typename U>
inline constexpr bool is_specialization_v = is_specialization<T, U>::value;

为这样的事情编写“_v”帮助模板的正确方法是什么?还请尝试在答案中解释它是如何工作的,因为我对模板元编程还很陌生,而且我仍在努力解决一些概念。

【问题讨论】:

标签: c++ c++17 template-meta-programming template-specialization typetraits


【解决方案1】:

你的别名参数错误,应该和主模板一样:

template <typename T, template <typename...> typename Template>
inline constexpr bool is_specialization_v = is_specialization<T, Template>::value;

【讨论】:

  • 啊,我明白了,我想这是有道理的,但为什么和主模板一样呢?为什么我也不需要辅助模板的“帮助”模板?
  • @tjwrona1992 出于所有实际目的,不存在专业化。它们是一个配方,如果您获得这些模板参数,则以这种方式删除模板。因此,当您与模板交互时,您只会与主模板交互。
  • 您可能仍然需要专门化您的别名。但在这里,所有的“硬”部分都是用is_specialization 完成的。
  • 感谢你们两位在过去几天提供的帮助!我想我几乎完成了整件事的整理,但我仍然对最后一件事有疑问。我要去谷歌一下,但我可能还有一个问题要问,哈哈。
猜你喜欢
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 2011-01-02
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多