S.H*_*S.H 10 c++ templates stl template-argument-deduction
我正在寻找一种方法来提供一个带模板(STL)容器的函数,但需要它的元素是某种类型(例如int).
这些函数调用应该是VALID:
std::vector<int> Argument;
void foo( Argument );
std::list<int> Argument
void foo( Argument );
std::deque<int> Argument
void foo( Argument );
...etc
Run Code Online (Sandbox Code Playgroud)
这些函数调用应该是INVALID:
std::vector<float> Argument;
void foo( Argument );
std::list<double> Argument
void foo( Argument );
std::deque<char> Argument
void foo( Argument );
...etc
Run Code Online (Sandbox Code Playgroud)
有没有办法模板"foo",以便int接受容器,但不接受具有不同元素类型的容器?
最好,本
qua*_*dev 13
使用标准库语义:
foo,而不是一个容器:它使你的功能很多更通用std::iterator_traits<Iterator>::value_type得到的值类型static_assertIterator的值类型是int(或者你想要的任何类型)示例:
#include <list>
#include <vector>
template<typename Iterator>
void foo(Iterator begin, Iterator end)
{
static_assert(std::is_same<int, typename std::iterator_traits<Iterator>::value_type>::value,
"Invalid value type : must be int");
}
int main() {
std::list<int> l1;
std::vector<int> v1;
foo(std::begin(l1), std::end(l1)); // OK
foo(std::begin(v1), std::end(v1)); // OK
std::vector<float> v2;
foo(std::begin(v2), std::end(v2)); // Doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
注意:
foo需要访问容器的特定成员函数(如Deduplicator所述,出于性能原因可能会发生这种情况),那么您可能需要坚持使用Container参数:示例:(注意获取的差异value_type,如MooingDuck所指出的,这是使其适用于数组所必需的):
template <typename Container>
void foo(const Container& c)
{
static_assert(std::is_same<int, std::iterator_type<decltype(std::begin(c))>::value_type>::value, "Invalid value type : must be int");
// Use c member function(s)
}
Run Code Online (Sandbox Code Playgroud)
STL容器有typedef value_type,所以你可以使用它.
然后你可以禁止static_assert:
template <typename Container>
void foo(const Container& )
{
static_assert(std::is_same<int, typename Container::value_type>::value, "expect int type");
}
Run Code Online (Sandbox Code Playgroud)
或通过SFINAE
template <typename Container>
typename std::enable_if<std::is_same<int, typename Container::value_type>::value>::type
foo(const Container& )
{
}
Run Code Online (Sandbox Code Playgroud)
您可以简单地使用 Sfinae,如下所示:
#include <type_traits>
#include <utility>
template <typename Container>
typename std::enable_if< std::is_same< typename Container::value_type, int >::value,
void >::type foo(Container& c) {
/* code here */
};
Run Code Online (Sandbox Code Playgroud)
如果容器没有与“int”相同的值类型,则将从“foo”的重载集中删除。您还可以使用其他特征,例如is_convertible更容易接受相关类型。使用不具有 int 值的容器调用 foo 会被编译器报告为没有合适的重载候选者。
如果您没有 C++11 支持,我上面使用的东西可以在 Boost 中作为 C++98/03 的替代品。
| 归档时间: |
|
| 查看次数: |
202 次 |
| 最近记录: |