编辑:根据反馈对提供的代码进行了重写以帮助说明问题。
假设我有一个方法template<T> do_foo(T)
,并且我仅使用std::enable_if
来定义返回值。
这使我可以编写如下的签名:
// templates_top.h
template<typename T>
std::enable_if_t<std::is_fundamental<T>::value, int> do_foo(T bb)
{
return 0;
}
我还可以在后面添加更多关于
do_foo
的定义——templates_top.h
不需要为每个可能进入do_foo
的东西都有前置声明——任何调用do_foo
的地方都可以。
现在假设我有几个类,它们的do_foo
实现最好不要在头文件中。
// templates_a.h
#include "./templates_top.h"
#include "./templates_b.h"
class LocalTypeA {
public:
LocalTypeB* internal_;
};
template<typename T>
std::enable_if_t<std::is_same<T, LocalTypeA>::value, int> do_foo(T bb)
{
// Some detailed business logic
// With recursive do_foo for member
return do_foo<LocalTypeB>(*(bb.internal_));
}
// templates_b.h
#include "templates_top.h"
class LocalTypeB {
public:
bool the_val = false;
};
template<typename T>
std::enable_if_t<std::is_same<T, LocalTypeB>::value, int> do_foo(T bb)
{
// Some detailed business logic here
// specific to LocalTypeB that ideally isn't in a header
// Also not that do_foo is called recursively for the std::is_fundamental type
return do_foo<bool>(bb.the_val);
}
所有这些都在头文件中运行良好。但现在 - 我们想将这个复杂的业务逻辑从标题中移出。
我们无法像
template<> do_foo(LocalTypeB)
一样完全专业化它,因为没有通用实现 template<typename T> do_foo(T)
。如果我们使其通用,则 std::is_fundamental
重载变得模糊。有没有办法让我编写此场景,以便
templates_top.h
保留其对LocalTypeA/B
的无知和对std::is_fundamental
的使用- 允许
LocalTypeA/B
的重载移到各自的实现文件中,并仍然解决std::enable_if
签名函数
值得说明的是,这只是我曾经遇到的一个现实问题的相当大的简化,我一直有些难以解释——我更希望能找到在更大规模上解决类型冲突核心的方法。
代码示例 在这里 - 编译为
g++ main_a.cpp
或 g++ main_b.cpp
。
T
和R
的顺序以启用对T
的推导? - 463035818_is_not_a_numberdo_foo
,所以这可能对您没有帮助。您必须展示模板如何用于不同类型,以便清楚为什么需要特化。 - Marek R