简体   繁体   中英

How can i instantiate a static member method template of a class?

I want to instantiate My::name() method for different types passed to it:

#include <string>
#include <iostream>

namespace prw
{
    class My
    {
    public:
        template <typename TYPE>
        static std::string name(TYPE v);
    };
}

std::string prw::My::name(int v)
{
    return "Ok";
}


int main()
{
    std::cout << prw::My::name(1) << std::endl;

    return 0;
}

Compiler output:

main.cpp:14:17: error: no declaration matches 'std::string prw::My::name(int)'
   14 |     std::string prw::My::name(int v)
      |                 ^~~
main.cpp:10:28: note: candidate is: 'template<class TYPE> static std::string prw::My::name(TYPE)'
   10 |         static std::string name(TYPE v);
      |                            ^~~~
main.cpp:6:11: note: 'class prw::My' defined here
    6 |     class My
      |           ^~

By the way stackoverflow tells me that:

It looks like your post is mostly code; please add some more details.

Although my question is simple and self-explanatory by just viewing the code and the complirer's output.

What i'm doing wrong? Damn:(

You are trying to specialize the template, not instantiate it. The syntax for specialization would be:

template<>
std::string prw::My::name(int v)
{
    return "foo";
}
// And if you want to further specialize for other types:
template<>
std::string prw::My::name(bool v)
{
    return "bar";
}

Specialization defines how the template would work on some type. Instantiation causes the compiler to generate the code for it and check its validity earlier than it would normally would. Normally the compiler would do that at the first call site of the function with the specific type but for a couple of reasons you might want to change when that happens (eg this lets you define templates outside of your header files). The syntax for explicit instantiation, specifically by means of providing explicit instantiation definitions is:

namespace prw
{
    class My
    {
    public:
        template <typename TYPE>
        static std::string name(TYPE v)
        {
            return "Ok"; // notice how name has a body now
        }
    };
}

template std::string prw::My::name(int v); // name is instantiated here instead of below


int main()
{
    std::cout << prw::My::name(1) << std::endl;

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM