[英]ambiguous template specialization in variadic function template
我正在嘗試編寫一個可變參數 function 模板來計算struct
的字節大小。 這將用於我正在從事的網絡編程項目。 第一步我想出了這個沒有可變參數模板的工作:
#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;
}
我在我的Ubuntu 20.04
筆記本電腦上使用g++
9.3.0
編譯,它運行良好。 但是,如果我嘗試將其設為可變參數模板,則會遇到不同的編譯錯誤。 這個可變參數模板的重點是能夠像下面這樣編寫,以便實現不依賴於x
和y
類型的顯式知識。
這是錯誤的代碼#1
#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;
}
我有
錯誤:'std::size_t sizeT() 的模版特化 'sizeT' 模棱兩可
注意:候選者是:'template std::size_t sizeT()'
注意:模板<class T, class... Ts> std::size_t sizeT()'
錯誤代碼 #2。 如果我將可變參數模板放在不同的位置:
#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;
}
我有
錯誤:重載 'sizeT<int8_t>()' 的調用不明確
注意候選:'std::size_t sizeT() [with T=signed char; std::size_t = long unsigned int]'
注意候選:'std::size_t sizeT() [with T=signed char; TS={}; std::size_t = long unsigned int]'
錯誤:重載 'sizeT()' 的調用不明確
注意候選:'std::size_t sizeT() [with T=Position; std::size_t = long unsigned int]'
注意候選:'std::size_t sizeT() [with T=Position; TS={}; std::size_t = long unsigned int]'
我有點理解案例#2,但我不明白#1。 我怎樣才能做到這一點? 非常感謝你。
你不使用可變參數...
你可能會做 (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)>();
}
但是sizeT<Position, Position>
將返回2 * sizeof(Position)
而不是2 * sizeT<Position>
(這里是相同的)。
你可能會這樣做:
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)>());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.