草庐IT

c++ - 函数重载 - 定义顺序

coder 2024-02-04 原文

我正在尝试创建一个有一些复杂的库 resolve函数,调用一个简单的 foo功能。 resolve函数应该适用于 foo 的任何类型重载了。

foo库中提供的适用于一些基本类型,但我希望用户能够提供自己的重载版本 foo可用于 resolve .

这是一个非常简短的例子:

//IN THE LIBRARY
#include <iostream>

void foo(int i) { std::cout << "int " << i; }
void foo(float f) { std::cout << "float " << f; }

template <typename T>
void resolve(T arg) {
    //some complex computation
    foo(arg);
    //some more complutation
}

//IN THE USER CODE

void foo(const char* c) { std::cout << "cstring " << c; }

int main() {
    resolve(3);
    resolve(4.2f);
    resolve("abc");
    return 0;
}

问题是,foo 的用户定义重载出现在 resolve 的定义之后它是看不见的。我期待在实例化时 resolve<const char*> foo 的第三次过载会被看到——但事实似乎并非如此:

prog.cpp: In instantiation of ‘void resolve(T) [with T = const char*]’:
prog.cpp:16:15:   required from here
prog.cpp:8:5: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
  foo(arg);
  ~~~^~~~~
prog.cpp:3:6: note:   initializing argument 1 of ‘void foo(int)’
 void foo(int i) { std::cout << "int " << i; }
      ^~~

所以,我的问题是,我怎样才能让它发挥作用?有没有一些简单的方法来获得 resolve 的一部分?由用户提供(例如,在 foo 重载方面)?

一些约束:

  • 我希望它在编译时得到解决。
  • 用户代码应该尽可能简单。例如,有 resolve采用一个额外的 lambda 参数——对于给定类型的 arg,它应该始终相同– 使用起来太复杂。

使用场景类似于重载std::less对于给定的自定义 T , 然后使用 std::sort除了 T 的数组外,无需任何其他参数应该排序。

最佳答案

有关模板中名称查找的规则详尽here :

For a dependent name used in a template definition, the lookup is postponed until the template arguments are known, at which time ADL examines function declarations [...] that are visible from the template definition context as well as in the template instantiation context, while non-ADL lookup only examines function declarations [...] that are visible from the template definition context (in other words, adding a new function declaration after template definition does not make it visible except via ADL).

因此,您有两种选择:

  • 用户只能调用您的resolve参数要么具有您提供的特化(默认情况下),要么可以通过 Argument Dependent Lookup 找到.基本上,它们必须在与它们传递的类型相同的命名空间中定义它们的重载。

    示例:https://godbolt.org/z/KCaO-s

  • 你做 foo用户可以专门化的模板。您提供自己的(默认)特化,用户稍后可以提供他们的和 resolve将为 resolve 选择可用的最佳模板特化在实例化时 (即调用 resolve 的位置)。

    示例:https://godbolt.org/z/AYn7FM


附录:
标准库有一个非常相似的问题;参见例如here如何定制例如std::swap实现用户的行为(如允许)。请特别注意,在 C++20 中,不再允许函数模板特化(仅允许类模板特化)。其原因详见 the corresponding paper .虽然上述建议比在任何地方都要求类特化更能让用户感到舒服,但您可能应该研究标准库决定采取更极端立场的原因。

关于c++ - 函数重载 - 定义顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53748373/

有关c++ - 函数重载 - 定义顺序的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  5. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  6. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  7. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  8. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  9. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  10. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

随机推荐