代码之家  ›  专栏  ›  技术社区  ›  ssb

C++SFINAE解析顺序

  •  4
  • ssb  · 技术社区  · 7 年前

    我有两个功能

    template <typename... Args>
    void foo(Args&&... args) { /* ... */ }
    
    template <typename... Args>
    void foo(const std::string& name, Args&&... args) { /* ... */ }
    

    目前,所有通话 foo("bar", /* arguments */) 尝试转到第一个函数,而不是第二个函数。我想对这些函数重新排序,以便SFINAE在第一个函数之前找到第二个函数。我不能使用 std::enable_if 检查字符数组/字符串,因为 Args... 包装可能包含 std::string& const char (&) [] .我该怎么做?

    2 回复  |  直到 7 年前
        1
  •  6
  •   NathanOliver    7 年前

    这里的问题是 "bar" std::string .再订购的数量不会增加 void foo(const std::string& name, Args&&... args) 调用,因为这需要在 void foo(Args&&... args)

    您可以使用 literal string operator “酒吧” 字符串使用 "bar"s 。这确实需要更改

    template <typename... Args>
    void foo(const std::string& name, Args&&... args) { /* ... */ }
    

    template <typename... Args>
    void foo(std::string&& name, Args&&... args) { /* ... */ }
    
    template <typename... Args>
    void foo(std::string& name, Args&&... args) { /* ... */ }
    

    “酒吧” 是一个prvalue,它将与主函数匹配,因为这将推导出一个右值引用,而右值引用优于常量左值引用。

        2
  •  6
  •   Tristan Brindle    7 年前
    template <typename... Args>
    void foo(Args&&... args) { /* ... */ }
    

    确切地 --如果需要任何类型的转换,那么编译器更愿意实例化第一个模板。

    std::string ,我们可以使用标准类型特征进行测试 std::is_convertible

    // General case
    template <typename First, typename... Rest,
              std::enable_if_t<!std::is_convertible<First, std::string>::value, int> = 0>
    void foo(First&& first, Rest&&... rest) { ... }
    
    // First argument can be converted to string
    template <typename... Args>
    void foo(const std::string& first, Args&&... args) { ... }
    

    Corilu link