Use a templated variadic template parameter as specialized parameter

别说谁变了你拦得住时间么 提交于 2019-12-05 14:37:14
dyp

It probably boils down to this:

template<class T, class U = int>
struct cat {};

template< template<class...> class Animal >
void foo()
{
    Animal<int> x; (void)x; // (A)
}

int main()
{
    foo<cat>();
}

This little innocent-looking program is accepted by clang++ and g++, but not by MSVC2013 Update 1.


Line (A) is the problematic one: I think in this example it's clear that the template template-parameter Animal should have two template parameters, when passing the class template cat.

It seems that clang++ and g++ support the use of default template arguments for this template template-parameter in line (A), while MSVC does not.

I do not know if the Standard requires either of them; see for example

It certainly appears to me that supporting the default template arguments is useful, since (as said in the active issue) the class templates of the Standard Library may have additional template parameters (with default arguments); and you'd need to know those implementation-details if you wanted to use them (directly) as template template-arguments.

Given the discussion which has happened I think maybe it would be time to consider a work-around. Since deducing the template template arguments seems to be the issue at hand, perhaps relaxing the requirements for MapType might be helpful.

template< typename MapType>
Expression Expression::substitute( MapType const& identifierToExpressionMap) const {
    return SubstitutionVisitor<MapType>(identifierToExpressionMap).substitute(something);
}

The caller is going to be compiled code calling a function and so the compiler will deduce the template arguments so basically you're pushing the responsibility of using the proper std::map or std::unordered_map onto the caller.

Now at least for most cases this may work. However it is possible to pass in some kind of container which compiles but doesn't actually have the right types. So ideally you'd still be wanting some kind of compile-time check to ensure MapType is supported (ie: either a std::map or std::unordered_map).

This could be via Boost concepts, or even just having two templated alias declarations - using enable_if you can ensure that the alias declaration is only available in two flavors: map or unordered_map.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!