我有一个模板化容器,将值存储在向量中。字符串或整数没有问题,但 size_t 值无法编译。编译器似乎假设我想用 int 而不是 size_t 值来初始化向量。我该如何解决这个问题?
#include <iostream>
#include <vector>
template <class ValueType>
class Container {
public:
template <typename... ValueTypes>
Container(ValueTypes&&... values) :
currentIndex(0),
values{ std::forward<ValueTypes>(values)... }
{}
const ValueType operator()() const {
return values[currentIndex];
}
protected:
size_t currentIndex;
std::vector<ValueType> values;
};
int main() {
Container<std::string> container1("10", "20", "30"); // ok
Container<int> container2(10, 20, 30); // ok
Container<size_t> container3(10, 20, 30); // compile error, assumed ints!
}
10
、20
和 30
确实是 int
文字,因此会出现缩小转换错误/警告。
您可以使用
u
(或 ULL
)后缀使它们的文字符合 size_t
:
Container<size_t> container3(10u, 20u, 30u);
有两种方法可供选择(第二种方法类型更安全,但需要使用稍微不同的语法)..
#include <iostream>
#include <vector>
#include <type_traits>
template <class type_t>
class Container {
public:
// Constructor 1
template <typename... args_t>
Container(args_t&&... args) :
m_currentIndex{}
{
// pre alocate memory to avoid resizing
m_values.reserve(sizeof...(args_t));
// use a fold expression to put all values in the vector
(m_values.emplace_back(std::forward<args_t>(args)),...);
}
// Constructor 2, more typesafe
template<std::size_t N>
Container(const type_t (&values)[N]) :
m_values{std::begin(values),std::end(values)}
{
}
// return a const& here so you avoid a copy
const type_t& operator()() const
{
return m_values[m_currentIndex];
}
protected:
size_t m_currentIndex;
std::vector<type_t> m_values;
};
int main()
{
// Constructor 1
Container<std::string> container1{"10", "20", "30"}; // ok
Container<int> container2{10, 20, 30}; // ok
Container<size_t> container3{10, 20, 30}; // compile error, assumed ints!
// Constructor 2
Container<std::string> container4{{"10", "20", "30"}}; // ok
Container<int> container5{{10, 20, 30}}; // ok
Container<size_t> container6{{10, 20, 30}}; // compile error, assumed ints!
}
问题是values
是一个左值表达式,因此从
values
到
size_t
的转换是一个缩小转换,从这个
int
左值到
size_t
是一个缩小转换。这可以从 dcl.init.list#7 中看出:
缩小转换是从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型的隐式转换,解决此问题的一种方法是显式地将后缀除非源是常量表达式,其整型提升后的值将适合目标类型。
u
写入每个文字。
Container<size_t> container3(10U, 20U, 30U);