草庐IT

c++ - 用于检测函数是否存在的 C++ 元函数问题

coder 2024-02-23 原文

我遇到了一个我不理解的 C++ 元函数问题。我正在使用 C++14 编译 Apple 的 clang 8.1.0 版本。说明问题的工作代码如下。

我从其他地方抄袭了一个元功能,我正在尝试使用它。它旨在检测名为“bananify”的函数,这些函数具有传递给元函数的类型的参数。你称之为...

BananifyDetector<int>::value 

如果它可以看到形式声明的函数,它应该返回 true ...

bananify(int)

问题是,只有在 BananifyFinder 的模板定义之前声明要搜索的函数,而不是在它的实例化之前,它才有效。所以在我的示例代码中,我希望两者兼而有之,

BananifyFinder<int>
BananifyFinder<std::string> 

使用下面的代码成功,但由于 bananify(std::string) 的定义位置,它失败了。

这令人沮丧,就好像我将函数检测器放在头文件中一样,我必须在客户端代码中包含顺序感知,这是一种极大的痛苦,并且在某些情况下可能无法正确处理。

我不确定这里发生了什么。它是 C++ 功能、clang 中的错误还是我做过的蠢事?

感谢任何帮助。

#include <iostream>
#include <type_traits>   
////////////////////////////////////////////////////////////////////////////////
// A bananify function to be detected
// This is successfully found.
double bananify(int)
{
  return 0.0;
}

/// A meta function that detects if a single argument function named 'bananify'
/// exists with takes an argument of the type passed to the metafunction.
///
/// Note, automatic casts will get in the way occasionally so if function
/// bananify(float) exists, a BananifyFinder<int>::value will return true.
template<class ARG1>
class BananifyFinder {
private :
  template<typename ...> using VoidT_ = void;

  template<typename A1, typename = void>
  struct Test_ : std::false_type
  {
    typedef void returnType;
  };

  template<typename A1>
  struct Test_<A1, VoidT_<decltype(bananify(std::declval<A1>()))>> : std::true_type
  {
    typedef decltype(bananify(std::declval<A1>())) returnType;
  };

public :
  typedef typename Test_<ARG1>::returnType returnType;
  constexpr static bool value = Test_<ARG1>::value;
};

////////////////////////////////////////////////////////////////////////////////
// A bananify function to be detected that takes std::strings
// This fails to be found, but if we move it before the declaration of BananifyFinder it
// will be found;
std::string bananify(std::string)
{
  return "s";
}

// dummy class with no bananify function to be found
class Nothing{};

// check the results of the metafunction 'T'
template<class T>
void CheckBanana(const std::string &str)
{
  using DetectedType = BananifyFinder<T>;
  std::cout << str << " detected is " << DetectedType::value << std::endl;
  std::cout << str << " returns is " << typeid(typename DetectedType::returnType).name() << std::endl << std::endl;
}

////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
  // this should print "BananifyFinder<int> 1 d"
  CheckBanana<int>("BananifyFinder<int> ");

  // this should print "BananifyFinder<std::string>  1 NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"
  // but it prints "BananifyFinder<std::string>  0 v"
  // FAILS
  CheckBanana<std::string>("BananifyFinder<std::string> ");

  // this should print "BananifyFinder<Nothing>  0 v"
  CheckBanana<Nothing>("BananifyFinder<Nothing> ");
}

最佳答案

模板分两个阶段进行解析。

在第一个中,解析独立于模板参数的表达式。在第二个中,依赖于模板的参数依赖项在Argument dependent lookup处被解析。执行。

decltype(bananify(std::declval<A1>()))>是参数依赖构造(取决于 A1 )。

来自 this page

And ADL examines function declarations with external linkage that are visible from both the template definition context and the template instantiation context (in other words, adding a new function declaration after template definition does not make it visible, except via ADL).

因此,您的代码会查看 std:: (使用 ADL)并且没有找到 bananify功能。

将其移动到模板实例化之前足以使其有资格进行查找。

关于c++ - 用于检测函数是否存在的 C++ 元函数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45838011/

有关c++ - 用于检测函数是否存在的 C++ 元函数问题的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  4. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

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

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

  6. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  7. 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

  8. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  9. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  10. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

随机推荐