当前位置: 首页 > 知识库问答 >
问题:

变函数模板中的歧义模板专门化

郝修为
2023-03-14

我试图编写一个可变函数模板来计算结构的字节大小。这将用于一个网络编程项目,我正在工作。第一步,我在没有工作的variadic模板的情况下想出了这个:

#include <cstdint>
#include <iostream>

struct Position
{
    int32_t x;
    int32_t y;
};

template<typename T>
inline std::size_t sizeT() { return sizeof(T); }

template<>
inline std::size_t sizeT<Position>() { return sizeT<int32_t>() + sizeT<int32_t>(); }
// if I change the definition of Position, I need to remember to change this function

int main(int argc, char* argv[])
{
    std::cout << "int8_t:" << sizeT<int8_t>() << std::endl;
    std::cout << "Position:" << sizeT<Position>() << std::endl;

    return 0;
}
#include <cstdint>
#include <iostream>

struct Position
{
    int32_t x;
    int32_t y;
};

template<typename T>
inline std::size_t sizeT() { return sizeof(T); }

template<>
inline std::size_t sizeT<Position>()
{
    return sizeT<decltype(Position::x), decltype(Position::y)>();
}

template<>
inline std::size_t sizeT<Position>() { return sizeT<int32_t>() + sizeT<int32_t>(); }


int main(int argc, char* argv[])
{
    std::cout << "int8_t:" << sizeT<int8_t>() << std::endl;
    std::cout << "Position:" << sizeT<Position>() << std::endl;

    return 0;
}

错误代码#2。如果我将variadic模板放在不同的位置:

#include <cstdint>
#include <iostream>

struct Position
{
    int32_t x;
    int32_t y;
};

template<typename T>
inline std::size_t sizeT() { return sizeof(T); }

template<>
inline std::size_t sizeT<Position>() { return sizeT<int32_t>() + sizeT<int32_t>(); }


template<>
inline std::size_t sizeT<Position>()
{
    return sizeT<decltype(Position::x), decltype(Position::y)>();
}

int main(int argc, char* argv[])
{
    std::cout << "int8_t:" << sizeT<int8_t>() << std::endl;
    std::cout << "Position:" << sizeT<Position>() << std::endl;

    return 0;
}

我得到了

错误:重载的'size t ()'调用不明确

共有1个答案

姚星宇
2023-03-14

你不用变体...

你可以做(C++17)

template <typename ... Ts>
constexpr std::size_t sizeT() { return (0 + ... + sizeof(Ts)); }

template <>
constexpr std::size_t sizeT<Position>()
{
    return sizeT<decltype(Position::x), decltype(Position::y)>();
}

演示

您可以改为:

template <typename... Ts>
struct tag{};

template <typename T>
constexpr std::size_t sizeT(tag<T>) { return sizeof(T); }

template <typename ... Ts>
constexpr std::size_t sizeT(tag<Ts...>) { return (0 + ... + sizeT(tag<Ts>())); }

template <typename ... Ts>
constexpr std::size_t sizeT(tag<Ts>...) { return (0 + ... + sizeT(tag<Ts>())); }

constexpr std::size_t sizeT(tag<Position>)
{
    return sizeT(tag<decltype(Position::x), decltype(Position::y)>());
}

演示

 类似资料:
  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。

  • 我目前正在研究可变参数模板,作为消化我一直在阅读的一些内容的一个小练习,我编写了一个小函数来输出其所有参数类型的名称: 令我惊讶的是,这是使用VC 12.0编译的,并且(似乎)工作得很好。 当只剩下一个参数时,由于重载之间的不确定性,我预计会出现错误,因为我了解到模板参数包可以为空/包含0个参数。 所以我的问题是为什么这行得通?“潜在的歧义”是如何解决的?两个函数的签名不是都只有一个参数吗?我觉得

  • 现在我想将它专门化为一个特定的值: 这无法用(版本4.6、4.7、4.8和4.9)编译: 不同命名空间中“template void foo::function()”的专门化[-fpermissive]

  • 我有以下模板方法: 但是我得到了那些奇怪的链接错误: /usr/lib/gcc/x86_64-redhat-linux/4.4。7/../../../../包括/c/4.4。7/例外:62:void MyStruct::readField(std::basic_istream)的多重定义 如何专门化此成员函数? 编辑 这种方法在以下方面起作用: 或者使用s或在类外使用

  • 我有一段代码,它是做模板专门化的常用模式。为了移除main函数第一行中为Processor1指定DataType1的要求,我想改为接收一个template模板参数。看起来using指令不支持分配“open”模板参数,而且我在web中找不到任何这样的示例(可能我没有使用适当的关键字进行搜索...) 所以问题很“简单”,我如何让这段代码编译呢?在FindDefaultProcessor中,使用type