rvalue参数无法在函数重载中解析

时间:2017-12-16 02:05:15

标签: c++ c++11 variadic-templates overloading rvalue-reference

如何在main()编译中创建最后一行?

#include <initializer_list>
#include <type_traits>
#include <functional>

template <typename T>
struct foo {
    foo(std::initializer_list<T>) { }

    template <typename C> struct is_foo : std::false_type { };
    template <typename U> struct is_foo<foo<U>> : std::true_type { };

    template <typename Compare>
    std::enable_if_t<!is_foo<Compare>::value> bar(foo&, Compare comp) {
        bool b = comp(T(), T());  // This line compiles thanks to is_foo<Compare>.
    }

    void bar(foo&& f) { bar(std::forward<foo>(f), std::less<T>()); }

    template <typename... Foos>
    void bar(Foos&&...) { }
};

int main() {
    foo<int> f = {1,2,3};
    f.bar({4,5,6});  // Compiles fine
    f.bar(f,f);  // Compiles fine (thanks to is_foo<Compare>)
    f.bar(f,{4,5,6});  // Won't compile
}

应该调用foo<T>::bar(Foos&&...)

Test.cpp:27:17: error: no matching function for call to 'foo<int>::bar(foo<int>&, <brace-enclosed initializer list>)'
  f.bar(f,{4,5,6});  // Won't compile
                 ^
Test.cpp:13:44: note: candidate: template<class Compare> std::enable_if_t<(! foo<T>::is_foo<C>::value)> foo<T>::bar(foo<T>&, Compare) [with Compare = Compare; T = int]
  std::enable_if_t<!is_foo<Compare>::value> bar(foo&, Compare comp) {
                                            ^~~
Test.cpp:13:44: note:   template argument deduction/substitution failed:
Test.cpp:27:17: note:   couldn't deduce template parameter 'Compare'
  f.bar(f,{4,5,6});

2 个答案:

答案 0 :(得分:2)

不确定你究竟想要什么,但是,如果你的意图是获得一个可变参数({1}}接收零个或多个bar()参数(或可用于初始化{{1的参数)的函数嗯...如果你接受参数数量的限制(比如63,在下面的例子中),就有一个技巧WF我认为showed one time可以根据你的情况进行调整。

如果您定义foo<T>模板别名

foo<T>

和递归typer

template <typename T, std::size_t>
using typer = T;

允许定义所需的struct proBar功能,模板template <typename T, std::size_t N = 64U, typename = std::make_index_sequence<N>> struct proBar; template <typename T, std::size_t N, std::size_t... Is> struct proBar<T, N, std::index_sequence<Is...>> : public proBar<T, N-1U> { using proBar<T, N-1U>::bar; void bar (typer<T, Is>... ts) { } }; template <typename T> struct proBar<T, 0U, std::index_sequence<>> { void bar () { } }; 变为

bar()

以下是完整的编译示例

struct foo

答案 1 :(得分:0)

这很有效。

#include <initializer_list>
#include <type_traits>
#include <functional>

template <typename T>
struct foo {
    foo(std::initializer_list<T>) { }

    template <typename C> struct is_foo : std::false_type { };
    template <typename U> struct is_foo<foo<U>> : std::true_type { };

    template <typename Compare>
    std::enable_if_t<!is_foo<Compare>::value> bar(foo&, Compare comp) {
        bool b = comp(T(), T());  // This line compiles thanks to is_foo<Compare>.
    }

    void bar(foo&& f) { bar(std::forward<foo>(f), std::less<T>()); }

    template <typename... Foos>
    void bar(Foos&&...) { }
};

int main() {
    foo<int> f = { 1,2,3 };
    f.bar({ 4,5,6 });  // Compiles fine
    f.bar(f, f);  // Compiles fine (thanks to is_foo<Compare>)
    f.bar(f, foo<int>({ 4,5,6 }));  // Won't compile
}