C++ 是否可以重载模板函数以与std::vector的元素一起使用?

C++ 是否可以重载模板函数以与std::vector的元素一起使用?,c++,c++11,templates,polymorphism,stdvector,C++,C++11,Templates,Polymorphism,Stdvector,我试图让一个函数接受一个泛型的std::vector(template std::vector),然后调用一个模板函数,该函数在其所有元素上对特定(抽象)类型进行了专门化 我正试图找出如何使用专用版本,同时仍然能够使用通用版本,但我没有成功 我正在使用VisualStudio2019 这是我的代码: #include <iostream> #include <vector> //the abstract type struct Foo { virtual int

我试图让一个函数接受一个泛型的std::vector(template std::vector),然后调用一个模板函数,该函数在其所有元素上对特定(抽象)类型进行了专门化

我正试图找出如何使用专用版本,同时仍然能够使用通用版本,但我没有成功

我正在使用VisualStudio2019

这是我的代码:

#include <iostream>
#include <vector>

//the abstract type
struct Foo
{
    virtual int bar(unsigned int) const = 0;
};

//The 'template function' I mentioned
template<typename T>
void do_something_with_an_element(const T& value)
{
    std::cout << value;
}

//the specialised version I mentioned
template<>
void do_something_with_an_element<Foo>(const Foo& value)
{
    //Note: this is only a placeholder
    std::cout << "It's a foo. bar = " << value.bar(7) << std::endl;
}

//the function that takes the 'generic' std::vector
template<typename T>
void do_something_with_a_vector(const std::vector<T>& vec)
{
    for (auto element : vec)
    {
        //calling the function on all its elements
        do_something_with_an_element(element); //Here is the problem line
    }
}

struct foo_impl : public Foo
{
    int val;

    foo_impl(int _val)
        : val(_val)
    {}

    // Inherited via Foo
    virtual int bar(unsigned int _something) const override
    {
        //do whatever...
        return val;
    }
};

std::vector<int> int_vector = { 32, 3, 43, 23 }; 
std::vector<foo_impl> foo_vector = { foo_impl(3), foo_impl(9), foo_impl(13) };

int main()
{
    do_something_with_a_vector(int_vector); //fine
    do_something_with_a_vector(foo_vector); //compile error
}


#包括
#包括
//抽象类型
结构Foo
{
虚拟整数条(无符号整数)常量=0;
};
//我提到的“模板函数”
模板
void do_something_与元素(常量和值)
{
标准::cout[
1> T=foo_impl
1>        ]

1> C:\…\MSVC\14.20.27508\include\ostream(438):注意:可以是'std::basic_ostream&std::basic_ostream::operator为了选择
const Foo&
的专门化,应该进行从
Foo\u impl
Foo
的隐式转换。另一方面,通过选择
const T
编译器做了一个聪明的动作,它直接推断到类型(即
foo_impl
),因为这对编译器来说更容易


因此,<代码> FoO 的专门化被拒绝了,因为“代码<操作程序”没有发现超载,所以错误不知道为什么专门化工作不起作用。但是提供一个非模板的简单函数重载将完成这项工作,因为编译器优先考虑模板化的一个。@ Jejo,这就是我的想法。首先也是这样,但它不起作用,如果它的参数类型被改变为“代码> const FuffiIMPL和而不是<代码> const fo& ,它就开始工作了,但这当然不是可取的。C++中相当复杂……我如何使隐式转换发生?如果有转换操作符<代码>操作符const fo&()const

foo_impl
?@null会很好的工作,@Hiroki-Hmm…没有想到。这就是链接。我还在寻找相关的引用表格doc,附在答案中。添加到答案中。@JeJo-thx。是的,我也不知道这篇文章的确切相关段落。
        1>program.cpp
        1>C:\...\program.cpp(17): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const T' (or there is no acceptable conversion)
        1>        with
        1>        [
        1>            T=foo_impl
        1>        ]
        1>C:\...\MSVC\14.20.27508\include\ostream(438): note: could be 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_streambuf<char,std::char_traits<char>> *)'
        1>C:\...\MSVC\14.20.27508\include\ostream(413): note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(const void *)'
         ((list goes on...))
        1>C:\...\program.cpp(17): note: while trying to match the argument list '(std::ostream, const T)'
        1>        with
        1>        [
        1>            T=foo_impl
        1>        ]
        1>C:\...\program.cpp(35): note: see reference to function template instantiation 'void do_something_with_an_element<foo_impl>(const T &)' being compiled
        1>        with
        1>        [
        1>            T=foo_impl
        1>        ]
        1>C:\...\program.cpp(61): note: see reference to function template instantiation 'void do_something_with_a_vector<foo_impl>(const std::vector<foo_impl,std::allocator<_Ty>> &)' being compiled
        1>        with
        1>        [
        1>            _Ty=foo_impl
        1>        ]
        1>Done building project "program.vcxproj" -- FAILED.
        ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========```
template<typename T>
std::enable_if_t<!std::is_base_of_v<Foo, T>>
do_something_with_an_element(const T& value)
{
    std::cout << value;
}

void do_something_with_an_element(const Foo& value)
{
    std::cout << "It's a foo. bar = " << value.bar(7) << std::endl;
}