首页 > 解决方案 > Why does my template specialisation need to match the originals constraint?

问题描述

For example, in this code:

#include <iostream>
#include <type_traits>

template<typename T>
requires std::is_same_v<T,int> || std::is_same_v<T,float> || std::is_same_v<T,double>
bool foo(const T& value)
{
    return true;
}

template<>
bool foo<double>(const double& value)
{
    return false;
}


int main()
{
    std::cout << foo(12)    << std::endl;
    std::cout << foo(1.2f)  << std::endl;
    std::cout << foo(1.2)   << std::endl;

    return 0;
}

If I remove the || std::is_same_v<T,double> from the constraint then the third output will fail to compile.

But what I don't understand is why the specialisation can't sort of automatically define it's own constraint? The specialisation itself is indicative that whatever T is it should be a valid type, but now trying to use constraints requires that I "document" all the specialisation ahead of time. Consider a non-toy example where a specialisation does something wildly different, having that specialised type listed in the constraints would be confusing if the fallback version couldn't possible operate on the specialised type.

This seems to me like the compiler could automatically include the specialised types in the list of constraints, because I'm having trouble coming up with a case where a specialised type wouldn't just be considered a new constraint?

I'm hoping someone has an idea of whether this is a technical limitation for the compiler or whether there's another reason the committee decided to do it this way.

标签: c++templatesconstraintsc++20

解决方案


An explicit specialization of a template is defined relative to a primary template. Specializations cannot exist without a primary template. They are an alternative to that primary template.

During template instantiation, if a set of template arguments fail the constraint tests, then instantiating that template fails. It is instantiating a primary template that causes an explicit specialization to be used. If instantiating the primary template failed for those template arguments, then you can't get at its specializations either.


推荐阅读