提问人:quant 提问时间:8/17/2023 最后编辑:Vlad from Moscowquant 更新时间:8/17/2023 访问量:78
区分函数和类 (functor)
distinguish between functions and classes (functor)
问:
我有一个函数和类,叫做 GreaterThan。
template <typename T>
bool GreaterThan(const T& number)
{
return number > 100;
}
template <typename T>
class GreaterThan
{
private:
T value;
public:
GreaterThan(T x) : value(x) {}
~GreaterThan() {}
bool operator()(T& compare)
{
return compare > value;
}
};
我怎样才能区分:
std::find_if(v1.begin(), v1.end(),GreaterThan<int>); // error
std::find_if(v1.begin(), v1.end(),GreaterThan<int>(100));
并让编译器知道 1) 应该调用函数?
答:
6赞
Vlad from Moscow
8/17/2023
#1
来自 C++ 20 标准(13 个模板)
7 类模板的名称不得与其他模板相同 模板、类、函数、变量、枚举、枚举器、 命名空间,或在同一作用域 (6.4) 中键入,但 13.7.6. 除了函数模板可以被同名的非模板函数 (9.3.4.6) 或其他 同名函数模板 (13.10.4),模板名称 在命名空间作用域或类作用域中声明应是唯一的,因为 范围。
因此,您的代码无效,因为类模板与函数模板同名。
如果模板在不同的命名空间中声明,则使用限定名称。
这是一个演示程序,
#include <iostream>
#include <vector>
#include <algorithm>
namespace N1
{
template <typename T>
bool GreaterThan( const T &number )
{
return number > 3;
}
}
namespace N2
{
template <typename T>
class GreaterThan
{
private:
T value;
public:
GreaterThan( const T &x ) : value( x ) {}
~GreaterThan() {}
bool operator()( const T &compare ) const
{
return compare > value;
}
};
}
int main()
{
std::vector<int> v1 = { 1, 2, 3, 4, 5 };
auto it1 = std::find_if( v1.begin(), v1.end(), N1::GreaterThan<int> );
auto it2 = std::find_if( v1.begin(), v1.end(), N2::GreaterThan<int>( 3 ) );
if ( it1 != v1.end() ) std::cout << "*it1 = " << *it1 << '\n';
if ( it2 != v1.end() ) std::cout << "*it2 = " << *it2 << '\n';
}
程序输出为
*it1 = 4
*it2 = 4
如果在同一作用域中使用非模板类和函数,则对于类类型的对象,请使用详细类型说明符。例如
#include <iostream>
#include <vector>
#include <algorithm>
bool GreaterThan( const int &number )
{
return number > 3;
}
class GreaterThan
{
private:
int value;
public:
GreaterThan( const int &x ) : value( x ) {}
bool operator()( const int &compare ) const
{
return compare > value;
}
};
int main()
{
std::vector<int> v1 = { 1, 2, 3, 4, 5 };
auto it1 = std::find_if( v1.begin(), v1.end(), GreaterThan );
auto it2 = std::find_if( v1.begin(), v1.end(), class GreaterThan( 3 ) );
if ( it1 != v1.end() ) std::cout << "*it1 = " << *it1 << '\n';
if ( it2 != v1.end() ) std::cout << "*it2 = " << *it2 << '\n';
}
评论
0赞
Peter
8/17/2023
相关引用并非特定于 C++20 - 迄今为止,每个 C++ 标准中都有相同的措辞(在我写这篇文章时 - 我没有水晶球可以预测标准在未来将如何发展)。唯一的区别是包含部分和段落编号,以及标准之间的交叉引用不同(例如,在C++ 89/90中,引用在第14节“模板”,第5段中)。
0赞
Red.Wave
8/17/2023
ADL 可能提供了一种方法,但这也是糟糕的设计。ADL 实例化表达式可以包装在 lambda 中。
评论