c++ - 将特化添加到单 header "library"

标签 c++ templates lazy-evaluation

目前正在开发一个涉及一些轻型 TMP 的单标题“库”,它允许用户为其类型添加自定义/特化(作为具有实际用例的自学项目)。

我在自定义位方面遇到问题。

例子

// foo_library.h
void foo(int i) {}
void foo(bool b) {}

template<typename T>
void do_something(T t)
{
    foo(t);
}

// user_code.cpp: user adds specialisation for double
void foo(double d) {}

do_something(42);    // ok
do_something(false); // ok
do_something(3.14);  // error: do_something has not seen double overload

注意:这是关于模板实例化的——我很清楚顺序(“看到了一些东西”)在 C 系列中很重要。

知道模板实例化是惰性的,我假设模板是就地实例化的,即已经看到双重特化。显然不是这样:(

我似乎遗漏了一些基本技术或概念,因为那里有代码允许用户将他们的自定义“注入(inject)”到模板繁重的仅 header 库(std: :swap 或 nlohmann::json 浮现在脑海中)

问题:我需要什么技术来启用这种自定义注入(inject)功能,只需让用户在某个库命名空间中定义适当的函数?

我想到的事情:

  • 将实现分散到多个 header 上,并让用户在所有自定义之后包括最后一个 header :容易出错并且可能不会扩展到玩具项目以外的任何项目

  • 使用 section-include-guards(Symbolic C++ 这样做,但不是为了定制)将 header 分成多个部分:需要用户通过 EVERY_CUSTOMIZATION_DEFINED_HERE 宏或类似宏选择加入,不想这样。

  • 将事物包装到类模板中,希望实例化表现不同。不。

最佳答案

正如评论中所述,基本类型没有 ADL,因此您可以只添加虚拟参数(具有相关名称):

template<typename> struct Tag{};

void foo(int i, Tag<int>) { std::cout << "int:" << i << std::endl;}
void foo(bool b, Tag<bool>) {std::cout << "bool:" << b << std::endl;}

template<typename T>
void do_something(T t)
{
    foo(t, Tag<T>{});
}

//user_code.cpp: 用户为double添加特化

void foo(double d, Tag<double>) {std::cout << "double:" << d << std::endl;}
int main() {
    do_something(42);    // ok
    do_something(false); // ok
    do_something(3.14);  // use double overload :)
}

Demo

关于c++ - 将特化添加到单 header "library",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53361723/

相关文章:

vb.net - Lazy(Of T) 使用/初始化

c++ - 如何避免在 linux 上使用系统标准 C/C++ 库?

c++ - 将整数转换为位表示

c++ - 如何在 C++ 中使用 mmap 将整数数组正确写入文件

C++ 推断尖括号内类型的模板参数

c++ - 在此上下文中如何使用 CRTP 删除虚拟方法?

c++ - 是否有比 boost::object_pool 更快的 C++ 堆分配/释放机制可用?

c++ - (2012) Visual C++ LNK2019 错误,也许是模板问题?

haskell - 通过递归示例理解 Haskell 中的非严格性

c++ - 我怎样才能制作自己的惰性迭代器?