gpt4 book ai didi

c++ - 成员的部分特化

转载 作者:行者123 更新时间:2023-11-30 03:28:39 24 4
gpt4 key购买 nike

尝试专门化成员方法。
阅读上一个问题:std::enable_if to conditionally compile a member function
我很能理解我做错了什么。

#include <string>
#include <iostream>
#include <type_traits>

template<typename T>
class Traits
{
};

struct Printer
{
template<typename T>
typename std::enable_if<!std::is_function<decltype(Traits<T>::converter)>::value, void>::type
operator()(T const& object)
{
std::cout << object;
}
template<typename T>
typename std::enable_if<std::is_function<decltype(Traits<T>::converter)>::value, void>::type
operator()(T const& object)
{
std::cout << Traits<T>::converter(object);
}
};

template<>
class Traits<std::string>
{
public:
static std::size_t converter(std::string const& object)
{
return object.size();
}
};

int main()
{
using namespace std::string_literals;

Printer p;

p(5);
p("This is a C-string");
p("This is a C++String"s); // This compiles.
}

编译给出:

> g++ -std=c++1z X.cpp
X.cpp:42:5: error: no matching function for call to object of type 'Printer'
p(5);
^
X.cpp:14:5: note: candidate template ignored: substitution failure [with T = int]: no member named 'converter' in 'Traits<int>'
operator()(T const& object)
^
X.cpp:20:5: note: candidate template ignored: substitution failure [with T = int]: no member named 'converter' in 'Traits<int>'
operator()(T const& object)
^

它们似乎都失败了,因为它们看不到方法converter。但我正在尝试使用 SFINE 和 std::enable_if 来识别此函数不存在,因此只实例化其中一种方法。

每种类型都会生成相同的错误:

X.cpp:43:5: error: no matching function for call to object of type 'Printer'
p("This is a C-string");
^
X.cpp:14:5: note: candidate template ignored: substitution failure [with T = char [19]]: no member named 'converter' in 'Traits<char [19]>'
operator()(T const& object)
^
X.cpp:20:5: note: candidate template ignored: substitution failure [with T = char [19]]: no member named 'converter' in 'Traits<char [19]>'
operator()(T const& object)
^

注意:它编译为 std::string 版本。

最佳答案

您可以使用私有(private)辅助函数,并使用重载决策来优先于正 SFINAE-d 重载 - 而不是负 SFINAE-d 重载:

struct Printer
{
template <class T>
void operator()(T const& object) {
call_impl(object, 0);
}

private:
// selected if Traits<T>::converter exists and is a function
// preferred in this case because int is better than ...
template<typename T>
typename std::enable_if<std::is_function<decltype(Traits<T>::converter)>::value, void>::type
call_impl(T const& object, int)
{
std::cout << Traits<T>::converter(object);
}

// selected if either Traits<T>::converter doesn't exist or isn't a function
template<typename T>
void call_impl(T const& object, ...)
{
std::cout << object;
}

};

我们将在 C++2a 中使用约束函数获得的一个好处是我们可以在没有额外帮助的情况下做到这一点:

struct Printer
{
template <class T>
requires std::is_function<decltype(Traits<T>::converter)>::value
void operator()(T const& object)
{
std::cout << Traits<T>::converter(object);
}

template <class T>
void operator()(T const& object)
{
std::cout << object;
}
};

关于c++ - 成员的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46392948/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com