我有一个通用 vector 类,其中我实现了一个接受仿函数的构造函数。这个想法是调用仿函数来初始化 vector 中的每个元素,仿函数的单个参数是元素索引。
但是,当传递与 vector 元素类型不同类型的标量时,这会干扰我的“来自标量”构造函数:
template <typename T, int N>
struct SomeVectorClass
{
T values[N];
SomeVectorClass() {}
SomeVectorClass(T scalar)
{
for (int i = 0; i < N; i++) values[i] = scalar;
}
template <typename InitFunctionType>
SomeVectorClass(InitFunctionType initFunction)
{
for (int i = 0; i < N; i++) values[i] = initFunction(i);
}
};
...
SomeVectorClass<int, 2> a([&] (int i) { return i; }); // This works
SomeVectorClass<int, 2> b(123); // This works
SomeVectorClass<int, 2> c(123.f); // This causes error "called object type 'float' is not a function or function pointer"
我对 c 的期望是编译器自动将 123.f
转换为 123
,然后调用“来自标量”构造函数(在本例中接受 int
)。
三个问题:
- 重载决策是否首选 lambda 构造函数,因为它不需要强制转换?
- 有没有办法在没有
std::enable_if
或类似黑客的情况下完成这项工作? - 如果不是,如果
InitFunctionType
是仿函数,我将如何使用std::enable_if
仅启用仿函数构造函数?
预先感谢您的宝贵时间!
编辑:忘记提及,出于性能原因,我无法使用 std::function
。该类需要内联友好。
最佳答案
构造函数模板是首选,因为它是精确匹配,而 T
构造函数需要转换。首选精确匹配。
这正是 enable_if
所遇到的问题。存在来解决。您需要从重载决策集中删除构造函数模板,除非它实际上可以使用 int
进行调用。 :
template <typename F,
typename = typename std::result_of <F(int)>::type>
SomeVectorClass (F func) { }
这样,就可以使用 float
进行构建或char
将选择您的T
构造函数。这是唯一的候选人!
注意:std::result_of
不一定是 SFINAE 友好的 ( N3462 )。上面的代码适用于 gcc 4.9.2,但不适用于 gcc 4.7.2。如果上面无法编译,类似
include/c++/4.7.2/type_traits:1834:9: error: ‘
std::declval<float>()
’ cannot be used as a function
然后你可以将“仿函数”构造函数重写为:
template <typename F,
typename = decltype(std::declval<F>()(std::declval<int>()))
SomeVectorClass (F func) { }
关于c++ - 通用 vector 类中的重载解析问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29966780/