如何使用概念来特化类型特征?

3
我正在尝试使用C++的概念来编写一个类型特征,该特征将根据其模板参数是基本类型还是非基本类型来生成不同的类型:
template<typename T>
concept fundamental = std::is_fundamental_v<T>;

template<typename T>
concept non_fundamental = !std::is_fundamental_v<T>;

以下代码按照预期工作:
void Print(fundamental auto value)
{
    std::cout << "fundamental\n";
}
void Print(non_fundamental auto value)
{
    std::cout << "non fundamental\n";
}

int main()
{
   Print(1); // prints "fundamental"
   Print(std::string("str")); // prints "non fundamental"
}

但是将相同的思路应用于类型特征并不起作用。

template<fundamental T>
struct SomeTypeTrait
{
    using type = T;
};

template<non_fundamental T>
struct SomeTypeTrait
{
    using type = std::shared_ptr<T>;
};


using ExpectedToBeDouble = SomeTypeTrait<double>::type;
using ExpectedToBeSharedPtrOfString = SomeTypeTrait<std::string>::type; // fails to compile

我遇到一个编译器错误(MSVC):

error C3855: 'SomeTypeTrait': template parameter 'T' is incompatible with the declaration

如何利用概念来实现所需的行为?

1个回答

6

显然,语法与我所想的略有不同。

以下是一个有效的解决方案:

template<typename T>
struct SomeTypeTrait {};

template<fundamental T>
struct SomeTypeTrait<T> // note the extra <T>
{
    using type = T;
};

template<non_fundamental T>
struct SomeTypeTrait<T> // note the extra <T>
{
    using type = std::shared_ptr<T>;
};

此外,其中一个专业化可以成为默认实现,使代码变得更加简短,并允许以后添加更多的专业化。
template<typename T>
struct SomeTypeTrait // default
{
    using type = std::shared_ptr<T>;
};

template<fundamental T>
struct SomeTypeTrait<T> // specialization for fundamental types
{
    using type = T;
};

5
问题在于你不能通过重载来改变结构体的行为,而是需要进行特化。只有函数可以进行重载。 - BoP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接