gpt4 book ai didi

c++ - 具有特征参数的模板特化函数

转载 作者:太空宇宙 更新时间:2023-11-04 12:53:09 24 4
gpt4 key购买 nike

我正在尝试为 Eigen 类型编写一些具有模板特化的函数,遵循这个问题:Eigen: type deduction in template specialization of base-class

我是这样写的:

#include <type_traits>
#include <Eigen/Core>

namespace isEigenPlainObjectBaseDetail {
template <typename T>
std::true_type test(const Eigen::PlainObjectBase<T>);
std::false_type test(...);
}
template <typename T>
struct isEigenPlainObjectBase :
public decltype(isEigenPlainObjectBaseDetail::test(std::declval<T>())) {};

template <typename T, typename Enable = void>
void foo(T& obj) {
std::cout << "Generic Called!\n";
}

template <typename T, typename std::enable_if<isEigenPlainObjectBase<T>::value>::type>
void foo(T& obj) {
std::cout << "Eigen Specialization Called!";
}

int main() {
Eigen::MatrixXd m;
Eigen::VectorXd v;
int i = 0;
foo(i);
foo(m);
foo(v);
return 0;
}

但这每次都会调用通用函数:

Generic Called!
Generic Called!
Generic Called!

我做错了什么?如何为具有特征矩阵和 vector 的函数编写模板特化?

最佳答案

不确定这是唯一的问题(没有安装 Eigen,所以我无法检查;抱歉)但是...

您可以部分特化结构和类,而不是函数。

所以这段代码

template <typename T, typename Enable = void>
void foo(T& obj) {
std::cout << "Generic Called!\n";
}

template <typename T, typename std::enable_if<isEigenPlainObjectBase<T>::value>::type>
void foo(T& obj) {
std::cout << "Eigen Specialization Called!";
}

不工作,我很惊讶编译。

编辑:正如 Quentin 所指出的(谢谢!),第二个模板参数的第二个是非类型参数;所以两个 foo() 之间没有冲突,但第二个被排除在外,因为非类型模板参数是 void 类型。这是不允许的。

要使用 SFINAE,您应该通过一个或一个结构;像

template <typename T, typename = void>
struct foo
{
static void func (T & obj)
{ std::cout << "Generic Called!\n"; }
};

template <typename T
struct foo<T, typename std::enable_if<isEigenPlainObjectBase<T>::value>::type>
{
static void func (T & obj)
{ std::cout << "Eigen Specialization Called!"; }
};

可以用作

foo<decltype(i)>::func(i);
foo<decltype(m)>::func(m);
foo<decltype(v)>::func(v);

也许你可以定义一个bar()模板辅助函数

template <typename T>
void bar (T & t)
{ foo<T>::func(t); }

然后简单地调用

bar(i);
bar(m);
bar(v);

或者使用标签调度可能更简单。

如果你定义了几个接收不同附加参数的foo()

template <typename T>
void foo (T &, std::false_type const &)
{ std::cout << "Generic Called!\n" }

template <typename T>
void foo (T &, std::true_type const &)
{ std::cout << "Eigen Specialization Called!"; }

您应该能够使用像这样的 bar() 辅助函数来选择正确的 foo()

template <typename T>
void bar (T & t)
{ foo(t, isEigenPlainObjectBase<T>{}); }

并且,和以前一样,简单地调用

bar(i);
bar(m);
bar(v);

[注意:未经测试]

关于c++ - 具有特征参数的模板特化函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47962830/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com